目录:
try-with-resources
jdk1.7后增加了try-with-resources,他是一个声明一个或多个资源的try语句。一个资源作为一个对象,必须在程序结束之后关闭。try-with-resources语句确保在语句的最后每个资源都被关闭,任何实现了java.lang.AutoCloseable和java.io.Closeable的对象都可以使用try-with-resource来实现异常处理和关闭资源。
1.7之前释放资源
public class demo {
public static void main(String[] args)throws Exception {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null)
br.close();
}
return null;
}
}
try-with-resources释放资源
package cn.milo.io;
import java.io.Closeable;
import java.io.IOException;
/******************************************************
****** @ClassName : TryCatchResources.java
****** @author : milo ^ ^
****** @date : 2018 01 15 17:34
****** @version : v1.0.x
*******************************************************/
public class TryCatchResources implements Closeable {
/*
1.如果是普通的try catch finally 中 try和finally都抛出异常,最终是finally抑制try中的异常,这个体现在main方法抛出的异常上,一个方法只能抛出一个异常 参照demo4
2.如果是try catch resources 中 try 和try catch resources 都抛出异常 , 最终try catch resources 中的异常被抑制 参照main2
3.如果以例【2】为基础添加finally的异常,最终inllay中的异常都会抛出 参照demo3 (和demo4中情况一样)
*/
private final boolean throwInClose;
private final String name;
public TryCatchResources(boolean throwInConstruction, boolean throwInClose, String name) throws IOException {
this.throwInClose = throwInClose;
this.name = name;
if (throwInConstruction) {
throw new IOException("throwing in construction");
}
}
@Override
public void close() throws IOException {
if (throwInClose) {
throw new IOException("throwing in close");
}
System.out.println(name + " is closing...");
}
public static void main(String[] args)throws Exception {
try (TryCatchResources d1 = new TryCatchResources(false, false, "a"); //构造方法 > try内 > try cathc resources内(close中的)
TryCatchResources d2 = new TryCatchResources(true, false, "b");) {
throw new IOException("in main1");
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
System.out.println("----end1----");
//demo2
try (TryCatchResources d1 = new TryCatchResources(false, false, "a");
TryCatchResources d2 = new TryCatchResources(false, true, "b");) {
throw new IOException("in main2");
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
System.out.println("----end2----");
//demo 3
try (TryCatchResources d2 = new TryCatchResources(false, true, "b");) {
int k = 1/0;
} finally {
int k = 1/0;
}
System.out.println("----end3----");
//demo 4
try {
throw new IOException("in main4");
} finally {
int k = 1/0;
}
}
}
结论
使用了try-with-resources语句之后,有可能会出现两个异常,一个是try块里的异常,一个是调用close函数里抛出的异常。
当然,平时我们写代码时,没有关注到。一般都是再抛出close函数里的异常,前面的异常被丢弃了。也就是在finally抛出异常后,try块里的异常被丢弃了。
如果在调用close函数时出现异常,那么前面的异常就被称为Suppressed Exceptions,因此Throwable还有个addSuppressed函数可以把它们保存起来,当用户捕捉到close里抛出的异常时,就可以调用Throwable.getSuppressed函数来取出close之前的异常了。
当close方法内,try内,finally内同时出现异常时。依然是只有finally的异常会抛出。因为一个方法只能有一个异常抛出。try和close中的异常都被抑制了。