Exception异常类及其处理

宋正兵 on 2020-11-22

异常

异常指的是导致程序中断执行的一种指令流,出现错误之后,整个程序将不会按照既定的方式进行执行,而是中断。

比如下面的数学计算将会产生异常:

1
2
3
4
5
6
7
public class JavaDemo {
public static void main(String[] args) {
System.out.println("【1】**** 程序开始执行 ****");
System.out.println("【2】**** 数学计算 : " + 10 / 0); // Exception in thread "main" java.lang.ArithmeticException: / by zero
System.out.println("【3】**** 程序执行完毕 ****");
}
}

如果希望程序依然可以正常完成,就需要一个完善的异常处理机制,以保证程序的顺利执行。

处理异常

基本的异常处理结构:

1
2
3
4
5
6
7
8
9
10
11
try{
// 可能出现异常的够
} [catch (异常类型 异常对象){
// 异常处理
} catch (异常类型 异常对象){
// 异常处理
} catch (异常类型 异常对象){
// 异常处理
} ...] [finally {
// 不管异常是否处理都要执行;
}]

可以是: try...catchtry...catch...finallytry...finally 组合使用。

修改代码处理异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class JavaDemo {
public static void main(String[] args) {
System.out.println("【1】**** 程序开始执行 ****");
try {
System.out.println("【2】**** 数学计算 : " + 10 / 0);
} catch (ArithmeticException e) {
e.printStackTrace(); // 处理异常
}
System.out.println("【3】**** 程序执行完毕 ****");
}
}
/* output
【1】**** 程序开始执行 ****
java.lang.ArithmeticException: / by zero
【3】**** 程序执行完毕 ****
*/

此时即便出现了异常,程序也可以正常执行完毕,所以此时的设计属于一个合理的设计。

throws关键字和throw关键字的区别

  • throw:在代码块中使用,主要是手工进行异常对象的抛出;
  • throws:在方法定义上使用,表示将此方法中可能产生的异常明确告诉给调用处,由调用处进行处理。

在方法的声明上使用 throws 关键字来进行异常类型的标注,例如:

1
2
3
4
5
6
7
8
9
10
11
class MyMath {
// 这个代码执行的时候可能会产生异常,如果产生异常了调用处处理
public static int div (int x, int y) throws Exception {
return x / y;
}
}
public class JavaDemo {
public static void main(String[] args) throws Exception {
System.out.println(MyMath.div(10, 2));
}
}

其中主方法本身也是一个方法,那么主方法也可以向上继续抛出异常,也可以就在主方法中使用try…catch进行处理。

throw 关键字用来手工产生异常的实例化对象,并且进行异常的抛出处理。例如:

1
2
3
4
5
6
7
8
9
public class JavaDemo {
public static void main(String[] args) {
try{ // 对象不再是由系统生成的,而是由手工定义的
throw new Exception("自己抛着玩的对象");
} catch (Exception e) {
e.printStackTrace();
}
}
}

RuntimeException

首先需要明确的是,Exception类及其子类是Throwable类的子类,表示合理的应用程序可能希望捕获的状况。在程序之中可以处理的异常的最大类型就是Throwable,它提供有两个子类:

  • Error:程序还未执行出现的错误,如系统崩溃、虚拟机错误、动态链接失败等无法恢复或不可能捕获的错误,开发者无法处理;
  • Exception:程序中出现的异常,开发者可以处理。

image.png

特别值得说的一点是Exception又分为不受检查异常(绿色背景)和受检查异常(红色背景)。

不受检查异常(runtime exceptions) 是因程序员没有进行必要的检查,由于疏忽而引起的错误,经典的RuntimeException如下:

  • java.lang.NullPointerException
  • java.lang.ArithmaticException
  • java.lang.ArrayIndexoutofBoundsException

受检查异常(checked exceptions) 必须被 try…catch 语句块所捕获,或在方法声明里使用 throws 关键字,确保在编译时被捕获处理。命名为受检查异常是因为 Java 编译器要进行检查,java 虚拟机也要进行检查,以确保这个规则得到遵守。

如果出现RuntimeException错误,那么一定是程序员的错误。