Q:请对比Exception和Error,另外,运行时异常与一般异常有什么区别?
典型回答
Exception和Error都是继承了Throwable类,在java中类型的实力才可以被抛出或者捕获,它是异常处理的基本组成类型。
Exception和Error体现了java平台设计者对不同异常情况的分类。Exception是程序正常运行时,可以预料的意外情况,可能并且应该被捕获,进行相应的处理。Error是程序正常运行时,不大可能出现的情况,绝大部分的Error都会导致程序处于非正常的、不可恢复的状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是Error的子类。
Exception又分为可检查异常和不可检查异常,可检查异常在源代码里必须显示地进行捕获处理,这是编译检查的一部分。不检查异常就是所谓的运行时异常,类似NullPointerException、ArrayIndexOutOfBoundsException之类的,通常是可以避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
常见异常
扩展问题:NoClassDefFoundError和ClassNotFoundException有什么区别?
看看下面这段代码
try {
// 业务代码
// …
Thread.sleep(1000L);
} catch (Exception e) {
// Ignore it
}
这段代码虽短,但已经违反了异常处理的两个基本原则。
第一,尽量不要捕获Exception这样的通用异常,而是应该捕获特定的异常,这里Thread.sleep()抛出的是InterruptedException。在日常开发合作中,我们有义务让自己的代码能够直观地体现出尽量多的信息,而泛泛的Exception之类,恰恰隐藏了我们的目的。另外,我们也要保证程序不会捕获到我们不希望捕获的异常。比如,你可能更希望RuntimeException被扩散出来,而不是被捕获。
第二,不要生吞异常。生吞异常,往往是基于假设这段代码不可能发生,或者感觉忽略异常是无所谓的,但是千万不要在产品代码中做出这种假设!如果不把异常抛出来,或者也没有输出到日志之类,程序可能在后续代码以不可控的方式结束。没人能够轻易判断究竟是哪里抛出异常,以及是什么原因产生了异常。