异常处理机制的三个主要问题
What
异常类型回答了什么被抛出
Where
异常堆栈跟踪回答了在哪抛出
Why
异常信息回答了为什么被抛出
异常处理机制
抛出异常
当一个方法出现错误引发异常时,方法创建异常对象,并交付给运行时系统,系统对象中包含了异常类型和异常出现时的程序状态等异常信息,运行时系统负责寻找处置异常的代码并执行
捕获异常
在方法抛出异常后,运行时系统将转为寻找合适的异常处理器【即ExceptionHandler】,潜在的异常处理是异常发生时依次存留在调用栈中的方法的集合,当异常处理器所能处理的异常类型与抛出的异常类型相符合时,即为合适的异常处理器,运行时系统从发生异常的方法开始依次回查调用栈中的方法,直至找到含有异常处理器的方法并执行,当运行时系统遍历了调用栈都没找到合适的处理器,则运行时系统终止,Java程序终止
异常处理原则
具体明确
抛出的异常应能通过异常类名和message准确说明异常的类型和产生异常的原因
提早抛出
应尽可能早的发现并抛出异常,便于精确定位问题
延迟捕获
异常的捕获和处理应尽可能延迟,让掌握更多信息的作用域来处理异常
异常体系
如下图 Java 异常体系的顶级类是 Throwable
从概念上分析
2. Exception 是程序可以处理的异常,在捕获异常后,程序可以从错误中恢复过来
Java 异常概览Exception
RuntimeException
运行时异常,即不可预知的,编译器编译程序时无法感知的异常;如经常发生的 NullPointerException、IndexOutOfBoundsException等
非RuntimeException
编译器可以检查的异常,可预知;即在程序不处理该异常时,编译无法通过;如经常可见的 IOException、ClassNotFoundException等
Error
Error 是致命的错误,程序无法处理这些错误;即 Error 类是与 JVM 相关的问题,如果系统崩溃、内存不足、Java 堆栈溢出等;如 StackOverflowError【深递归导致栈被耗尽而抛出的异常】、OutOfMemoryError【内存溢出异常】
异常相关注意的点
1. 在异常处理中,如果 catch方法中包含return语句,并且finally语句中也包含return语句时,即使 catch方法中捕获到相应的异常后,最终catch中的 return 也不会被执行,而是会执行 finally中的语句
2. 仅捕获可能出现异常的代码段,不要用一个大 try包住整个代码段
3. 不要用异常控制代码流程
4. try-catch 消耗性能的原因. 一方面 try-catch 块影响 JVM 的优化,另一方面异常对象实例需要保存栈快照等信息,开销较大【遇到一个异常,便会实例化一个Exception,并且会对栈进行快照】
总结
从责任角度看;
1. Error 属于 JVM 需要承担的责任
2. RuntimeException 是开发者需要承担的责任
3. 非 RuntimeException【Checked Exception 可检查异常】是 Java编译器应该承担的责任
网友评论