Exception和Error有什么区别?

典型的回答是这样的:

    Exception 和 Error都继承了Throwable类,在java中只有Throwable类型的实例才可以被抛出(Throw)或者捕捉(catch),它是异常处理机制的基本组成类型。

   Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应的处理。

      Error指在正常情况下,不大可能出现的情况,绝大部门的Error都会导致程序处于非正常的,不可恢复状态。既然是非正常情况,所以不便于也不需要捕获。比如常见的OutOfMemoryError之类,都是Error的子类。

   Exception类又分为可检查异常(checked)和不检查异常(unchecked),可检查异常在源码里必须显示的进行捕获处理,这是编译期检查的一部分。

    不检查异常就是所谓的运行时异常,类似NullPointerException,ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误。

考点分析:

  分析Exception 和 Error的区别,是从概念角度考察了Java处理机制,总的来说,还处于理解层面,面试者只要阐述清楚就好。

在日常的编程中如何处理好异常呢?

  第一,理解Throwable,Exception,Error的设计和分类。比如,掌握应用广泛的子类,以及如何自定义异常,如下图:

    

有些子类需要重点理解下,比如NoClassDefFoundError 和 ClassNotFoundException有什么区别,这也是经典的题目。

第二,理解Java语言中操作Throwable的元素和实践。如try-catche-finally块,throw,throws关键字等,随着JAVA语言的发展,引入了更加便利的特性,比如try-with-resources和multiple catch。代码如下

    try(BufferedReader br = new BufferedReader(br)){
            
        }catch(Exception  | IOExcetion e){
            
        }

知识扩展:

  前面谈了很多概念性的东西,接下来结合一些代码用例进行分析。

        try {
            // 业务代码
            //
            Thread.sleep(1000L);
        } catch (Exception e) {
            //
        }

这段代码很短,但是已经违反了异常处理的两个基本原则。

第一,尽量不要捕获类似Exception这样的通用异常,而是应该捕获特定异常。

Thread.sleep(1000L);这段代码抛出的InterruptedException。
第二,不要生吞异常
生吞异常往往是基于假设这段代码可能不会发生,或者感觉忽略异常时无所谓的。来看第二段代码,如下
try {
            // 业务代码
            //
        } catch (IOException e) {
            e.printStackTrace();
        }

这段代码没有任何问题,但是不要这么处理。

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

  • try-catch代码段会产生额外的性能开销,会影响JVM对代码进行优化,所以建议仅捕获有必要的代码,不要一个大try包住整段代码,不要用异常控制流程代码,很低效。
  • JAVA每实例化一个Exception,都会对当时的栈进行快照,这是一个相对比较重的操作,如果发生的非常频繁,这个开销可就不能被忽视了。

  • 不要推诿或者延迟处理异常,就地解决最好,并需要实实在在的进行处理,而不是只捕捉,不动作
  • 一个函数尽管抛出了多个异常,但是只有一个异常可被传播到调用端,最后被抛出的异常时唯一被调用端接收的异常,其他异常都会被吞没掩盖。如果调用端要知道造成失败的最初原因,程序中就不能掩盖异常

猜你喜欢

转载自www.cnblogs.com/zhjxtf/p/9355892.html