02、谈一谈Java中的Error和Exception

Error和Exception的联系

继承结构:Error和Exception都是继承于Throwable,RuntimeException继承自Exception。

Error和RuntimeException及其子类称为未检查异常(Unchecked exception),其它异常成为受检查异常(Checked Exception)。

 

Error和Exception的区别

Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。

Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

 

未检查异常(运行时异常)和受检查的异常

Exception又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception )

未检查异常(RuntimeException):其特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try……catch捕获,也没有用throws抛出,还是会编译通过。如除数为零ArithmeticException、错误的类型转换、数组越界访问和试图访问空指针等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。

受检查的异常(IOException等):这类异常如果没有try……catch也没有throws抛出,编译是通不过的。这类异常一般是外部错误,例如文件找不到、试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

 

throw 和 throws两个关键字有什么不同

throw 是用来抛出任意异常的,你可以抛出任意 Throwable,包括自定义的异常类对象;throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常。如果方法抛出了异常,那么调用这个方法的时候就需要处理这个异常。

 

try-catch-finally-return执行顺序

1、不管是否有异常产生,finally块中代码都会执行;

2、当try和catch中有return语句时,finally块仍然会执行;

3、finally是在return后面的表达式运算后执行的,所以函数返回值是在finally执行前确定的。无论finally中的代码怎么样,返回的值都不会改变,仍然是之前return语句中保存的值;

4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

 

NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

 

java.lang.NoClassDefFoundError:

类加载器试图加载类的定义,但是找不到这个类的定义,而实际上这个类文件是存在的。

 

java.lang.ClassNotFoundException:

从规范说明看, java.lang.ClassNotFoundException 异常抛出的根本原因是类文件找不到。

 

碰到最多的是 java.lang.ClassNotFoundException。从异常的名字看,很容易理解这个异常产生的原因是缺少了 .class 文件,比如少引了某个 jar,解决方法通常需要检查一下 classpath 下能不能找到包含缺失 .class 文件的 jar。

 

java.lang.NoClassDefFoundError 异常,这个异常的来源根本不是因为缺少 .class 文件。而碰到这个异常的解决办法,一般需要检查这个类定义中的初始化部分(如类属性定义、static 块等)的代码是否有抛异常的可能,如果是 static 块,可以考虑在其中将异常捕获并打印堆栈等,或者直接在对类进行初始化调用(如 new Foobar())时作 try  catch。

 

我们从性能角度来审视一下 Java 的异常处理机制,有两个可能会相对昂贵的地方

1、try-catch 代码段会产生额外的性能开销,或者换个角度说,它往往会影响 JVM 对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;

与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。

 

2、Java 每实例化一个 Exception,都会对当时的栈进进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。

 

发布了96 篇原创文章 · 获赞 19 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章