1. Java 中的 Exception 是什么?
异常是 Java 传达给你的系统和程序错误的方式。在 java 中,异常功能是通过实现比如 Throwable,Exception,RuntimeException 之类的类,然后还有一些处理异常时候的关键 字,比如 throw,throws,try,catch,finally 之类的。 所有的异常都是通过 Throwable 衍 生出来的。Throwable 把错误进一步划分为 java.lang.Exception 和 java.lang.Error. java.lang.Error 用来处理系统错误,例如 java.lang.StackOverFlowError 或者 Java.lang.OutOfMemoryError 之类的。然后 Exception 用来处理程序错误,请求的资 源不可用等等。
2. Java 中的检查型异常和非检查型异常有什么区别?
检查型异常需要使用 try, catch 和 finally 关键字在编译期进行处理,否则编译器会报错。对于非检查型异常则不需要这样做。Java 中所有继承自 java.lang.Exception 类的异常都是检查型异常,所有继承自 RuntimeException的异常都被称为非检查型异常。你也可以查看下一篇文章来了解 更多关于检查型异常和非检查型异常之间的区别。
throw 和 throws 乍看起来是很相似的尤其是在你还是一个 java 初学者的时候。尽管他们看起来相似,都是在处理异常时候使用到的。 但在代码里的使用方法和用到的地方是不同的。throws 总是出现在一个函数头中,用来标 明该成员函数可能抛出的各种异常, 你也可以申明未检查的异常,但这不是编译器强制的。 如果方法抛出了异常那么调用这个方法的时候就需要将这个异常处理。另一个关键 字 throw 是用来抛出任意异常的,按照语法你可以抛出任意 Throwable (i.e. Throwable 或任何 Throwable 的衍生类) , throw 可以中断程序运行,因此可以用来代替 return . 最常 见的例子是用 throw 在一个空方法中需要 return 的地方抛出 UnSupportedOperationException 代码如下 : 1 private static voidshow() { 2 throw new UnsupportedOperationException("Not yet implemented"); 3 }
4. 什么是“异常链”?
“异常链”是 Java 中非常流行的异常处理概念,是指在进行一个异常处理时抛出了另 外一个异常,由此产生了一个异常链条。该技术大多用于将“ 受检查异常” ( checked exception)封装成为“非受检查异常”(unchecked exception)或者 RuntimeException。 顺便说一下,如果因为因为异常你决定抛出一个新的异常,你一定要包含原有的异常,这 样,处理程序才可以通过 getCause()和 initCause()方法来访问异常最终的根源。
5. 你曾经自定义实现过异常吗?怎么写的?
很显然,我们绝大多数都写过自定义或者业务异常,像 AccountNotFoundException。 在面试过程中询问这个 Java 异常问题的主要原因是去发现你如何使用这个特性的。这可以 更准确和精致的去处理异常,当然这也跟你选择 checked 还是 unchecked exception 息息 相关。通过为每一个特定的情况创建一个特定的异常,你就为调用者更好的处理异常提供 了更好的选择。相比通用异常(general exception),我更倾向更为精确的异常。大量的创 建自定义异常会增加项目 class 的个数,因此,在自定义异常和通用异常之间维持一个平 衡是成功的关键。
6. 如果执行 finally 代码块之前方法返回了结果,或者 JVM 退
出了,finally 块中的代码还会执行吗?
这个问题也可以换个方式问:“如果在 try 或者 finally 的代码块中调用了 System.exit(),结果会是怎样”。了解 finally 块是怎么执行的,即使是 try 里面已经使用 了 return 返回结果的情况,对了解 Java 的异常处理都非常有价值。只有在 try 里面是有 System.exit(0)来退出 JVM 的情况下 finally 块中的代码才不会执行。
7. Java 中 final,finalize,finally 关键字的区别
这是一个经典的 Java 面试题了。我的一个朋友为 Morgan Stanley 招电信方面的核心 Java 开发人员的时候就问过这个问题。final 和 finally 是 Java 的关键字,而 finalize 则是方 法。final 关键字在创建不可变的类的时候非常有用,只是声明这个类是 final 的。而 finalize()方法则是垃圾回收器在回收一个对象前调用,但也 Java 规范里面没有保证这个方 法一定会被调用。finally 关键字是唯一一个和这篇文章讨论到的异常处理相关的关键字。 在你的产品代码中,在关闭连接和资源文件的是时候都必须要用到 finally 块。