Java异常体系知识点总结
这段时间进行了对Java异常体系的学习,这里总结一些比较经典的问题;
1. 异常结构体系
- 所有的异常都是由Throwable继承而来
- 由于程序错误导致的异常为RuntimeException,即运行时异常,运行时异常不需要捕捉,即运行时异常出现时能通过编译,但不能通过运行;
- 异常分为受查异常和非受查异常,RuntimeException和Error属于非受查异常,其他都属于受查异常,受查异常必须被捕捉,否则编译就不通过;
(比如ClassNotFoundException就属于受查异常,Class.forName(“xx”)时就必须捕捉ClassNotFoundException异常)
2. 基础语法
首先回顾一下异常处理的一般标准格式:
try {
}catch (Exception e) {
}finally {
}
注意几点:
-
try不能单独使用,必须搭配catch和finally中的一个或两个;
-
可以有多个catch块(但前面的catch里面的异常类型不能包含后面的异常类型,否则报错);
-
在JDK7的时候引入了try-with-resources和multiple catch(多个catch);
(参考代码如下)try(FileReader reader = new FileReader("xx"); FileWriter writer = new FileWriter("xx")) { //try-with-resources }catch (IOException | NullPointerException e) { //multiple catch e.printStackTrace(); }
-
异常处理的基本原则:
- 尽量不要捕捉通用异常(即Exception),捕捉特定异常能更助你发现问题;
- 不要忽略处理异常(即catch后需要输出异常信息,方便定位);
3. 典型问题
1. 异常对程序性能的影响
- try-catch块会产生额外的开销,因为JVM在处理try-catch块的时候,会影响到JVM对代码的优化,所以不要出现没必要的try-catch块;
- Java每实例化一个Exception,都会对当时的栈进行快照,这是一个相对比较重的操作,如果发生的比较频繁,效率就会很低下;
(所谓的对栈进行快照就是记录当前栈中发生这个异常的位置等各种信息,所以开销很大)
2. 常见的运行时异常
3. Error和Exception的区别(⭐)
- 共同点 :它们都继承自Throwable类,在Java中,只有Throwable或其子类才能够被抛出或捕获
- Exception是程序运行中,可以预期的意外情况,并且可以通过try-catch块进行捕捉处理;
Exception又分为运行时异常(属于非受查异常)和受查异常;
运行时异常编译能通过,但运行的时候如果出现这类异常,程序就会终止;而受查异常编译就通过不了,必须进行try-catch块捕捉或者用throws字句声明向上抛出 - Error描述了Java运行时的突发非正常情况,应用程序不能抛出此类异常,这种错误一旦出现,就不可恢复,程序只能终止;出现Error比如内存资源耗尽等
StackOverflowError、OutOfMemoryError都属于Error
4. throw和throws的区别
- throw语句用在方法体内表示抛出异常由方法体内的语句处理,执行throw一定是抛出了某类异常;
- throws用在方法声明的后面,该方法的调用者必须对其异常进行处理,throws代表可能会出现某种异常,但不一定会发生这种异常;
5. NoClassDefFoundError和ClassNotFoundException有什么区别(⭐)
- 首先最大的区别:一个是Error,一个是Exception嘛;
- ClassNotFoundException是当我们使用Class.forName()或者ClassLoader.loadClass以及使用**ClassLoader.findSystemClass()**在运行时加载类的时候,如果类没有被找到,就会抛出这个异常,这是一个受查异常;
- NoClassDefFoundError是JVM或者ClassLoader尝试加载类的时候却找不到类订阅导致的,也就是说要查找的类在编译的时候是存在的,运行的时候却找不到,就会出现这个异常;
例如先创建一个类,编译,删除其class文件,再运行,就会产生这个Error;
6. 部分语法规则
1. catch中也发生异常的情况
try {
int i = 10 / 0;
System.out.println("try");
} catch (Exception e) {
int j = 2 / 0;
System.out.println("catch");
} finally {
System.out.println("finally");
}
System.out.println("main");
输出:
finally
Exception in thread “main” java.lang.ArithmeticException: / by zero
at www.yy.listReview.DeleteList.main(DeleteList.java:24)
2. finally中出现异常的情况
try {
System.out.println("try");
} catch (Exception e) {
System.out.println("catch");
} finally {
int k = 3 / 0;
System.out.println("finally");
}
System.out.println("main");
输出:
try
Exception in thread “main” java.lang.ArithmeticException: / by zero
at www.yy.listReview.DeleteList.main(DeleteList.java:25)