Exception和Error
都继承了Throwable。
Error:正常情况不会出现,它会使程序变成非正常、不可恢复的状态,它是JVM侦测到的无法预期的错误。不可捕获,常见如:OutOfmemoryError
Exception:它是可恢复的异常,它分为可检查异常和运行时异常,
可检查异常(checked exception):需在代码中显式的捕获处理,如IO异常、SQL异常,JAVA编译器强制要求我们对这些异常进行处理。
运行时异常 (RuntimeException):运行时异常我们可以处理、也可以不处理进而交由虚拟机接管。一般是不处理,这样如果是线程会退出,如果是主程序会终止。比如空指针异常,产生原因是数据异常,通常处理方法是,舍弃该数据然后进行日志记录。自定义处理异常 还是 交由虚拟机使程序退出 要视情况而定。
NoClassDefFoundError和NoClassFoundException的区别
NoClassFoundException:属于检查异常,在类加载器加载某个类但却没找到时抛出,即,是在编译时。
NoClassDefFoundError:程序运行时,找不到某个类的定义时,会抛出该异常。
例:Test.java,在编译后,生成Test.class,我们在运行前将这个class删除,运行时就会因为找不到类的定义而抛出NoClassDefFoundError异常。
try…catch的应用规范
1.catch时要抓取具体的异常对象,而不是Exception这样一个笼统的对象。
2.不要生吞异常,面对异常我们要做的是,要么抛出、要么解决(包括log输出)
在捕获异常后,不要e.printStackTrace();
这样的输出我们很难判断或找寻,要把他放到log里。
Throw early, catch late 原则
Throw early尽早的抛出异常,如空指针异常,我们可以在使用可能为空的对象前使用Objects.requireNonNull(obj)
(该方法会判断obj是否为null并抛出NullPointerException异常)来尽早的抛出异常。
catch late对于捕获后的处理,输出日志或构建自定义异常再抛出,注意在日志输出中为了信息安全,不要包含业务数据、ip等。
性能问题
try…catch会产生额外的性能开销,所以缩小包裹范围,精准try关键代码。
Exception的实例化同时会对栈进行快照,也是有开销的。
try…catch…finally
在try中使用 return 会使控制权进入 finally 代码块,不止return,符合逻辑的break、continue也会这样。所以,在try…catch…finally结构中,极力避免try代码块中出现return、break、continue。finally的用途是清理资源,尽量不要放业务代码。
注意:如果try中的return返回了一个对象,在finally代码块中对对象进行了属性修改,那么这个方法返回的对象是经过finally代码块执行过的。
尝试接触使用JAVA7的 try-with-resources