
Java中,所有的异常都来源于java.lang包中的Throwable类,它有两个重要的子类,Exception(异常)和Error(错误)。
在以下 2种特殊情况下,finally 块不会被执行:
代码示例:
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.txt"));
br.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
1. 适用范围(资源的定义): 任何实现 java.lang.AutoCloseable 的对象
2. 关闭资源和 finally 块的执行顺序: 在 try-with-resources 语句中,任何 catch 或 finally 块在声明的资源关闭后运行
《Effecitve Java》中明确指出:
面对必须要关闭的资源,我们总是应该优先使用 try-with-resources 而不是try-finally。随之产生的代码更简短,更清晰,产生的异常对我们也更有用。try-with-resources语句让我们更容易编写必须要关闭的资源的代码,若采用try-finally则几乎做不到这点。
将上面的代码例子改造:
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
代码变得非常简洁。
注意:try-with-resource中声明的变量会隐式的加上final 关键字,所以无法再进行赋值。
在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。
因为父类已经把异常信息的操作都完成了,所在子类只要在构造时,将异常信息传递给父类通过super 语句即可。
代码示例:
public class CustomException extends Exception {
//无参构造方法
public CustomException(){
super();
}
//有参的构造方法
public CustomException(String message){
super(message);
}
// 用指定的详细信息和原因构造一个新的异常
public CustomException(String message, Throwable cause){
super(message,cause);
}
//用指定原因构造一个新的异常
public CustomException(Throwable cause) {
super(cause);
}
}
按照国际惯例,自定义的异常应该总是包含如下的构造函数:
finally块和return
首先一个不容易理解的事实:在 try块中即便有return,break,continue等改变执行流的语句,finally也会执行。
finally中的return 会覆盖 try 或者catch中的返回值。
finally中的return或异常会抑制(消灭)前面try或者catch块中的异常。