异常处理机制主要回答了三个问题?
What:异常类型回答了什么被抛出
Where:异常堆栈跟踪回答了在哪抛出
Why:异常信息回答了为什么被抛出
Error和Exception的区别?
Error和Exception均是继承于Throwable类。
Error是系统致命的错误,程序无法处理的系统错误,一般是指与JVM相关的问题,比如系统崩溃、虚拟机错误、内存空间不足、方法调用栈溢出(StackOverflowError)等。对于这些错误,Java编译器不做检查,这些错误仅靠程序本身是无法预防的。
Exception是程序可以处理的异常,可以被捕获并且可能恢复。遇到这些异常应该尽可能去处理,使程序恢复运行,而不应该随意终止异常。
总结:这两者对Java异常的一个分类,前者是程序无法处理的错误,后者是程序可以处理的错误。
RuntimeException和非RuntimeException的区别?
Exception有两个类型的子类,一个是RuntimeException,另一个是非RuntimeException。
RuntimeException表示运行时的异常,例如数组下标越界、空指针异常。该错误是不可预知的,程序应当自行避免,例如可以使用if语句判断一个对象是否为null来判断是否存在空指针异常的情况。
非RuntimeException是可预知的异常,例如文件不存在导致文件打开失败的异常。该异常时能被编译器检测到的,是必须处理的异常,如果不处理,程序就不能编译通过。
从责任角度看三种异常
- Error属于JVM需要负担的责任
- RuntimeException是程序应该负担的责任
- Checked Exception可检查异常是Java编译器应该负担的责任
常见Error以及Exception
RuntimeException
- NullPointerException 空指针引用异常
- ClassCastException 类型强制转换异常
- IllegalArgumentException 传递非法参数异常
- IndexOutOfBoundsException 下标越界异常
- NumberFormateException 数字格式异常(比如srting转数字转不过去)
非RuntimeException
- ClassNotFoundException 找不到指定class的异常
- IOException IO操作异常
Error
- NoClassDefFoundError 找不到class定义的异常
成因:类依赖的class或者jar不存在或者其他原因
- StackOverflowError 深递归导致栈被耗尽而抛出的异常
- OutOfMemoryError 内存溢出异常
ClassNotFoundException异常和NoClassDefFoundError异常的区别?
ClassNotFoundException继承自Exception继承,是一个可检查异常类。当动态加载Class的时候找不到类会抛出该异常。一般在执行Class.forName()、ClassLoader.loadClass()或ClassLoader.findSystemClass()的时候抛出。
NoClassDefFoundError继承自Error类。当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。
Java的异常处理机制
- 抛出异常:当一个方法出现错误引发异常时,方法创建异常对象并交付给运行时系统处理
- 捕获异常:当方法抛出异常后,运行时系统寻找合适的异常处理器ExceptionHandle处理异常(catch块),否则终止运行
Java异常的处理原则
- 具体明确:抛出的异常应能通过异常类名和message准确说明异常的类型和产生异常的原因
- 提早抛出:应尽可能早的发现并抛出异常,便于精确定位问题
- 延迟捕获:异常的捕获和处理应尽可能延迟,让掌握更多信息的作用域来处理异常
Finally块中的代码什么时候被执行?
如果try/catch中有return,finally中的代码在return之前执行。
当finally中有return语句,会覆盖try/catch中的return语句。
对于基本类型的数据,在finally中改变return的值,对其没有影响,而对引用类型有影响。(先将return的返回值存储在指定的位置,执行finally,再return)
Finally一定会被执行?
不一定。
- 程序还没进入try代码块,就出错了
- 程序在try中强制退出:System.exit(0)