说明
本文介绍 Java 的异常的类型及原理。
Java 异常的层次结构
Throwable 有两个直接的子类: Error、Exception。
- Error:JVM 内部的严重问题,比如资源不足等,无法恢复。处理方式:程序员不用处理。
- Exception:JVM 通过处理还可回到正常执行流程,即:可恢复。分 RuntimeException 和其他 Exception,或者说分为非受检异常 (unchecked exception) 和受检异常 (checked exception)。使用建议:将 checked exceptions 用于可恢复的情况,将 unchecked exception 用于编程的错误。
- RuntimeException(unchecked exception):处理或者不处理都可以(不需 try...catch... 或在方法声明时 throws)。
- 其他 Exception(checked exception):Java 编译器要求程序必须捕获(try...catch)或声明抛出(方法声明时 throws)这种异常。
为什么要对 unchecked 异常和 checked 异常进行区分?
编译器将检查你是否为所有的 checked 异常提供了异常处理机制,比如说我们使用 Class.forName () 来查找给定的字符串的 class 对象的时候,如果没有为这个方法提供异常处理,编译是无法通过的。
捕获异常再抛出
注意:下边的异常中的打印要用 System.err 而不是 System.out,不然会影响打印的顺序。
实例 1:包裹原异常再抛出
package com.example.a;
public class Demo {
public static void main(String[] args) throws Exception {
try {
int i = 1 / 0;
} catch (Exception e) {
System.err.println("自己捕获到异常:" + e.getMessage());
e.printStackTrace();
System.err.println("自己打印异常结束");
throw new Exception("自己抛出的异常", e);
}finally {
System.out.println("This is finally");
}
}
}
执行结果
自己捕获到异常:/ by zero
java.lang.ArithmeticException: / by zero
at com.example.a.Demo.main(Demo.java:6)
自己打印异常结束
Exception in thread "main" java.lang.Exception: 自己抛出的异常
at com.example.a.Demo.main(Demo.java:11)
Caused by: java.lang.ArithmeticException: / by zero
at com.example.a.Demo.main(Demo.java:6)
This is finally
实例 2:不包裹原异常再抛出
package com.example.a;
public class Demo {
public static void main(String[] args) throws Exception {
try {
int i = 1 / 0;
} catch (Exception e) {
System.err.println("自己捕获到异常:" + e.getMessage());
e.printStackTrace();
System.err.println("自己打印异常结束");
throw new Exception("自己抛出的异常");
}finally {
System.out.println("This is finally");
}
}
}
执行结果
自己捕获到异常:/ by zero
java.lang.ArithmeticException: / by zero
at com.example.a.Demo.main(Demo.java:6)
自己打印异常结束
Exception in thread "main" java.lang.Exception: 自己抛出的异常
at com.example.a.Demo.main(Demo.java:11)
This is finally