Throwable的两个子类:Error/Exception(面试中异常体系和JavaError问题)

1、error和exception有什么区别

  • error表示系统级的错误,是java运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是Java虚拟机抛出的。

  • exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序必须处理的问题。

2、运行时异常和一般异常有何不同

Java提供了两类主要的异常:runtimeExceptioncheckedException

一般异常(checkedException)主要是指IO异常、SQL异常等。对于这种异常,JVM要求我们必须对其进行cathc处理,所以,面对这种异常,不管我们是否愿意,都是要写一大堆的catch块去处理可能出现的异常。

运行时异常(runtimeException)我们一般不处理,当出现这类异常的时候程序会由虚拟机接管。比如,我们从来没有去处理过NullPointerException,而且这个异常还是最常见的异常之一。

出现运行时异常的时候,程序会将异常一直向上抛,一直抛到遇到处理代码,如果没有catch块进行处理,到了最上层,如果是多线程就由**Thread.run()抛出,如果不是多线程那么就由main.run()**抛出。抛出之后,如果是线程,那么该线程也就终止了,如果是主程序,那么该程序也就终止了。

其实运行时异常的也是继承自Exception,也可以用catch块对其处理,只是我们一般不处理罢了,也就是说,如果不对运行时异常进行catch处理,那么结果不是线程退出就是主程序终止

如果不想终止,那么我们就必须捕获所有可能出现的运行时异常。如果程序中出现了异常数据,但是它不影响下面的程序执行,那么我们就该在catch块里面将异常数据舍弃,然后记录日志。如果,它影响到了下面的程序运行,那么还是程序退出比较好些。

3. 什么是Java异常

答:异常是发生在程序执行过程中阻碍程序正常执行的错误事件。比如:用户输入错误数据、硬件故障、网络阻塞等都会导致出现异常。 只要在Java语句执行中产生了异常,一个异常对象就会被创建,JRE就会试图寻找异常处理程序来处理异常。如果有合适的异常处理程序,异常对象就会被异常处理程序接管,否则,将引发运行环境异常,JRE终止程序执行。 Java异常处理框架只能处理运行时错误,编译错误不在其考虑范围之内。

4. Java中的检查型异常和非检查型异常有什么区别?

这又是一个非常流行的Java异常面试题,会出现在各种层次的Java面试中。检查型异常和非检查型异常的主要区别在于其处理方式。检查型异常需要使用try, catch和finally关键字在编译期进行处理,否则编译器会报错。对于非检查型异常则不需要这样做。Java中所有继承自java.lang.Exception类的异常都是检查型异常,所有继承自RuntimeException的异常都被称为非检查型异常(运行时异常)。

5. Java中的NullPointerException和ArrayIndexOutOfBoundException之间有什么相同之处?

在Java异常面试中这并不是一个很流行的问题,但会出现在不同层次的初学者面试中,用来测试应聘者对检查型异常和非检查型异常的概念是否熟悉。顺便说一下,该题的答案是,这两个异常都是非检查型异常,都继承自RuntimeException。该问题可能会引出另一个问题,即Java和C的数组有什么不同之处,因为C里面的数组是没有大小限制的,绝对不会抛出ArrayIndexOutOfBoundException。

6. 在Java异常处理的过程中,你遵循的那些最好的实践是什么?

这个问题在面试技术经理是非常常见的一个问题。因为异常处理在项目设计中是非常关键的,所以精通异常处理是十分必要的。异常处理有很多最佳实践,下面列举集中,它们提高你代码的健壮性和灵活性:

  1. 调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException。

  2. catch块里别不写代码。空catch块是异常处理里的错误事件,因为它只是捕获了异常,却没有任何处理或者提示。通常你起码要打印出异常信息,当然你最好根据需求对异常信息进行处理。

3)能抛受控异常(checked Exception)就尽量不抛受非控异常(unchecked Exception)。通过去掉重复的异常处理代码,可以提高代码的可读性。

  1. 绝对不要让你的数据库相关异常显示到客户端。由于绝大多数数据库和SQLException异常都是受控异常,在Java中,你应该在DAO层把异常信息处理,然后返回处理过的能让用户看懂并根据异常提示信息改正操作的异常信息。

  2. 在Java中,一定要在数据库连接,数据库查询,流处理后,在finally块中调用**close()**方法。

7. 既然我们可以用RuntimeException来处理错误,那么你认为为什么Java中还存在检查型异常?

这是一个有争议的问题,在回答该问题时你应当小心。虽然他们肯定愿意听到你的观点,但其实他们最感兴趣的还是有说服力的理由。我认为其中一个理由是,存在检查型异常是一个设计上的决定,受到了诸如C++等比Java更早的编程语言设计经验的影响。绝大多数检查型异常位于java.io包内,这是合乎情理的,因为在你请求了不存在的系统资源的时候,一段强壮的程序必须能够优雅的处理这种情况。通过把IOException声明为检查型异常,Java 确保了你能够优雅的对异常进行处理。另一个可能的理由是,可以使用catch或finally来确保数量受限的系统资源(比如文件描述符)在你使用后尽早得到释放。 Joshua Bloch编写的 Effective Java 一书 中多处涉及到了该话题,值得一读。

8. throw 和 throws这两个关键字在java中有什么不同?

一个java初学者应该掌握的面试问题。 throw 和 throws乍看起来是很相似的尤其是在你还是一个java初学者的时候。尽管他们看起来相似,都是在处理异常时候使用到的。但在代码里的使用方法和用到的地方是不同的。throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常, 你也可以申明未检查的异常,但这不是编译器强制的。如果方法抛出了异常那么调用这个方法的时候就需要将这个异常处理。另一个关键字 throw 是用来抛出任意异常的,按照语法你可以抛出任意 Throwable (i.e. Throwable 或任何Throwable的衍生类) , throw可以中断程序运行,因此可以用来代替return . 最常见的例子是用 throw 在一个空方法中需要return的地方抛出 UnSupportedOperationException 代码如下 :

private static void show() {  
     throw new UnsupportedOperationException("Not yet implemented");
 }

9. 什么是“异常链”?

“异常链”是Java中非常流行的异常处理概念,是指在进行一个异常处理时抛出了另外一个异常,由此产生了一个异常链条。该技术大多用于将“ 受检查异常” ( checked exception)封装成为“非受检查异常”(unchecked exception)或者RuntimeException。顺便说一下,如果因为因为异常你决定抛出一个新的异常,你一定要包含原有的异常,这样,处理程序才可以通过getCause()和initCause()方法来访问异常最终的根源。

10. 你曾经自定义实现过异常吗?怎么写的?

很显然,我们绝大多数都写过自定义或者业务异常,像AccountNotFoundException。在面试过程中询问这个Java异常问题的主要原因是去发现你如何使用这个特性的。这可以更准确和精致的去处理异常,当然这也跟你选择checked 还是unchecked exception息息相关。通过为每一个特定的情况创建一个特定的异常,你就为调用者更好的处理异常提供了更好的选择。相比通用异常(general exception),我更倾向更为精确的异常。大量的创建自定义异常会增加项目class的个数,因此,在自定义异常和通用异常之间维持一个平衡是成功的关键。

11. JDK7中对异常处理做了什么改变?

这是最近新出的Java异常处理的面试题。JDK7中对错误(Error)和异常(Exception)处理主要新增加了2个特性,一是在一个catch块中可以出来多个异常,就像原来用多个catch块一样。另一个是自动化资源管理(ARM), 也称为try-with-resource块。这2个特性都可以在处理异常时减少代码量,同时提高代码的可读性。对于这些特性了解,不仅帮助开发者写出更好的异常处理的代码,也让你在面试中显的更突出。

12. 如果执行finally代码块之前方法返回了结果,或者JVM退出了,finally块中的代码还会执行吗?

这个问题也可以换个方式问:“如果在try或者finally的代码块中调用了System.exit(),结果会是怎样”。了解finally块是怎么执行的,即使是try里面已经使用了return返回结果的情况,对了解Java的异常处理都非常有价值。只有在try语句块里面是用System.exit(0)来退出JVM的情况下finally块中的代码才不会执行。

13. Java中final,finalize,finally关键字的区别

  • 这是一个经典的Java面试题了。我的一个朋友为Morgan Stanley招电信方面的核心Java开发人员的时候就问过这个问题。final和finally是Java的关键字,而finalize则是方法。final关键字在创建不可变的类的时候非常有用,只是声明这个类是final的。而finalize()方法则是垃圾回收器在回收一个对象前调用,但也Java规范里面没有保证这个方法一定会被调用。finally关键字是唯一一个和这篇文章讨论到的异常处理相关的关键字。在你的产品代码中,在关闭连接和资源文件的是时候都必须要用到finally块。

  • 每个Java中方法的覆盖是有规则的,一个覆盖的方法不能抛出的异常比原方法继承关系高。因为这里的start方法在超类中抛出了IOException,所有在子类中的start方法只能抛出要么是IOExcepition或是其子类,但不能是其超类,如Exception。

14. 常用的异常列表

Throwable的两个子类:Error/Exception(面试中异常体系和JavaError问题)_第1张图片

15. 你平时在项目中是怎样对异常进行处理的。

(1)尽量避免出现runtimeException 。例如对于可能出现空指针的代码,带使用对象之前一定要判断一下该对象是否为空,必要的时候对runtimeException也进行try catch处理。

(2)进行try catch处理的时候要在catch代码块中对异常信息进行记录,通过调用异常类的相关方法获取到异常的相关信息,返回到web端,不仅要给用户良好的用户体验,也要能帮助程序员良好的定位异常出现的位置及原因。例如,以前做的一个项目,程序遇到异常页面会显示一个图片告诉用户哪些操作导致程序出现了什么异常,同时图片上有一个按钮用来点击展示异常的详细信息给程序员看的。

16. final、finally、finalize的区别

(1)、final用于声明变量、方法和类的,分别表示变量值不可变,方法不可覆盖,类不可以继承

(2)、finally是异常处理中的一个关键字,表示finally{}里面的代码一定要执行

(3)、finalize是Object类的一个方法,在垃圾回收的时候会调用被回收对象的此方法。

17. try()里面有一个return语句,那么后面的finally{}里面的code会不会被执行,什么时候执行,是在return前还是return后?

只要没有在try块中显式调用System.exit()退出JVM,那么finally块中的语句一定会执行。return会返回finally块中的return信息。

你可能感兴趣的:(Java异常)