目录
2.1.3、NumberFormatException 异常(IllegalArgumentException异常)
2.1.4、ArrayIndexOutOfBoundsException 异常
一、异常的概念?
异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的 文件不存在、数组下标越界等。 在 Java 的异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。异常 类定义中包含了该类异常的信息和对异常进行处理的方法。
所谓异常处理,就是指程序在出现问题时依然可以正确的执行完。
二、异常的分类?
1、Error
Error是程序无法处理的错误,出现error都是程序运行时出现了比较严重的问题,与编写的代码无关,无法通过修改代码来解决,交由jvm来处理,不过一般情况下,jvm都会终止程序。
2、Exception
Exception是程序本身可以处理的异常,如除数为0的情况,加入了异常处理后,程序就会报ArithmeticException 异常,不过我们可以在catch语句快里面添加处理这个问题的语句,程序不会终止运行。
2.1、RuntimeException 运行时异常
运行时异常就是程序在运行时可能遇到的异常,如用户输入,假设我现在要求用户输入一个整形的数字,但用户输入了一串字符串,这时程序就会报InputMismatchException异常,不仅如此,还有许多程序运行时会遇到的异常,如被 0 除、数组下标越界、空指针等。下面看几个例子,以及它们的解决办法:
2.1.1、ClassCastException 异常
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
public class Test {
public static void main(String[ ] args) {
Animal a=new Dog();
Cat c=(Cat)a;
}
}
程序运行时会抛出如下异常:
解决办法:
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
public class Test {
public static void main(String[ ] args) {
Animal a = new Dog();
if (a instanceof Cat) {
Cat c = (Cat) a;
}
if(a instanceof Dog){
Dog c = (Dog) a;
}
}
}
判断一下a是哪个类,之后再赋值即可。
2.1.2、ArithmeticException 异常
public class Test {
public static void main(String[] args) {
int x = 0;
System.out.println(1 / x);
}
}
程序报错:
解决办法:
public class Test {
public static void main(String[] args) {
int x = 0;
if (x != 0) {
System.out.println(1 / x);
} else {
System.out.println("除数不能为0");
}
}
}
2.1.3、NumberFormatException 异常(IllegalArgumentException异常)
public class Test {
public static void main(String[] args) {
String str = "123abc";
System.out.println(Integer.parseInt(str));
}
}
程序报错:
解决办法:
public class Test {
public static void main(String[] args) {
String str = "123abc";
if(isNumber(str)){
System.out.println(Integer.parseInt(str));
}else{
System.out.println("字符串不是由纯数字组成,请检查:"+str);
}
}
public static boolean isNumber(String str){
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)<'0' || str.charAt(i)>9){
return false;
}
}
return true;
}
}
2.1.4、ArrayIndexOutOfBoundsException 异常
public class Test {
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
System.out.println(arr[5]);
}
}
程序报错:
解决办法:
public class Test {
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
//数组的索引是从0开始的,所以要使用数组的最后一个元素应该要数组的长度减1
System.out.println(arr[arr.length-1]);
}
}
2.1.5、NullPointerException 异常
public class Test {
public static void main(String[] args) {
String[] strArr = {"abcabc", "defd", null, "ghighighi", "jkljkljkljkl"};
for (int i = 0; i < strArr.length; i++) {
System.out.println(strArr[i].length());
}
}
}
程序报错:
解决办法:
public class Test {
public static void main(String[] args) {
String[] strArr = {"abcabc", "defd", null, "ghighighi", "jkljkljkljkl"};
for (int i = 0; i < strArr.length; i++) {
if(strArr[i]!=null){
System.out.println(strArr[i].length());
}else{
System.out.println("数组当前下标的值为空");
}
}
}
}
2.2、CheckedException 受检查异
所有不是 RuntimeException 的异常,统称为 Checked Exception,又被称为“受检异常”,如 IOException、SQLException 等以及用户自定义的 Exception 异常。 这类 异常在编译时就必须做出处理,否则无法通过编译。
例:
自定义了一个异常,这里的方法必须用try{}catch包起来,否则无法通过编译
三、异常的处理
1、捕获异常
try 语句指定了一段代码,该段代码就是异常捕获并处理的范围。在执行过程中,当任 意一条语句产生异常时,就会跳过该条语句中后面的代码。代码中可能会产生并抛出一种或 几种类型的异常对象,它后面的 catch 语句要分别对这些异常做相应的处理。 一个 try 语句必须带有至少一个 catch 语句块或一个 finally 语句块。
例:
public class Test {
public static void main(String[] args) {
int x = 0;
try {
System.out.println(1/x);
//上一句代码除数为0,try{}catch{}会捕获到异常,后面的语句不会执行
System.out.println(123);
} catch (Exception e){
System.out.println(e);
System.out.println("try{}catch{}捕获到异常后执行catch语句块里面的语句");
}
System.out.println(100);
}
}
运行结果:
也可以根多个catch:
运行结果:
接下来看加入finally的同时除数为0情况(会捕获到异常):
public class Test {
public static void main(String[] args) {
int x = 0;
try {
System.out.println(1/x);
//上一句代码除数为0,try{}catch{}会捕获到异常,后面的语句不会执行
System.out.println(123);
} catch (ArithmeticException e){
System.out.println(e);
System.out.println("这里捕获到异常了,后面的catch不会捕获了");
}catch (Exception e) {
System.out.println(e);
System.out.println("try{}catch{}捕获到异常后执行catch语句块里面的语句");
}finally {
//看try语句块里面第一句为return的情况
System.out.println("无论try语句块里面的语句是否有异常我都会执行");
}
System.out.println(100);
}
}
运行结果:
再来不会捕获到异常的情况(把x改为1,即除数不为0的情况):
public class Test {
public static void main(String[] args) {
int x = 1;
try {
System.out.println(1/x+"正常输出");
//上一句代码除数为0,try{}catch{}会捕获到异常,后面的语句不会执行
System.out.println(123+"前面一句没有异常我才能输出");
} catch (ArithmeticException e){
System.out.println(e);
System.out.println("这里捕获到异常了,后面的catch不会捕获了");
}catch (Exception e) {
System.out.println(e);
System.out.println("try{}catch{}捕获到异常后执行catch语句块里面的语句");
}finally {
//看try语句块里面第一句为return的情况
System.out.println("无论try语句块里面的语句是否有异常我都会执行");
}
System.out.println(100);
}
}
运行结果:
2、声明异常
当 CheckedException 产生时,不一定立刻处理它,可以再把异常 throws 出去。 在方法中使用 try-catch-finally 是由这个方法来处理异常。但是在一些情况下,当前 方法并不需要处理发生的异常,而是向上传递给调用它的方法处理。 如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常 规范在方法的首部声明该方法可能抛出的异常。
throw表示抛出异常,语法是: throw new 异常类型([异常信息])
throws表示用来声明方法可能会抛出那些异常: 语法是: throws 异常类型1,异常类型2…
3、自定义异常
在程序中,可能会遇到 JDK 提供的任何标准异常类都无法充分描述清楚我们想要 表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。
自定义异常类只需从 Exception 类或者它的子类派生一个子类即可。
自定义异常类如果继承 Exception 类,则为受检查异常,必须对其进行处理;如 果不想处理,可以让自定义异常类继承运行时异常 RuntimeException 类。
习惯上,自定义异常类应该包含 2 个构造器:一个是默认的构造器,另一个是带 有详细信息的构造器。
声明异常和自定义异常的例:
public class IntException extends Exception {
public IntException() {
}
public IntException(String message) {
super(message);
}
public IntException(String message, Throwable cause) {
super(message, cause);
}
public IntException(Throwable cause) {
super(cause);
}
//方法定义时声明异常
public void checkInt(int x) throws IntException {
if (x < 0) {
//条件满足时抛出异常
throw new IntException("请不要输入一个负数");
}
}
}
四、总结
1、try 代码段包含的是可能产生异常的代码
2、try 代码段后跟一个或多个catch代码段。(或跟一个finally代码段)
3、在jdk1.7之前每个catch代码段只声明一种其能处理的特定类型的异常,并提供处理的方法。 Jdk1.7之后,一个catch代码可以可以声明多个能处理的特定异常的类型,多个类型之间用”|”隔开
4、当异常发生时,程序会中止当前的流程去执行相应的catch代码段,即try语句块里面的某一语句发生异常后,在这个try语句块里面发生异常的这句语句后面的语句都不会再执行了。
5、写catch代码时,先捕获的异常的范围不能大于后捕获的异常的范围。
6、finally段的代码无论是否发生异常都执行。
7、自定义异常类如果继承 Exception 类,则为受检查异常,必须对其进行处理;如 果不想处理,可以让自定义异常类继承运行时异常 RuntimeException 类。