一、直接上代码
-
try-with-resource的写法,jdk1.7新增的
public static void main(String[] args) {
//try-with-resource用法
try (FileOutputStream fileOutputStream = new FileOutputStream(“test.txt")){
System.out.println(“文件写入");
fileOutputStream.write(1);
} catch (IOException e) {
System.out.println("异常处理");
e.printStackTrace();
}
}
-
jdk1.7之前的写法
public static void old(){
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream("text.txt");
System.out.println("文件写入开始");
fileOutputStream.write(1);
System.out.println("文件写入完成");
} catch (IOException e) {
System.out.println("文件写入异常处理");
e.printStackTrace();
} finally {
if(fileOutputStream != null){
try {
fileOutputStream.close();
}catch (IOException e){
System.out.println("流关闭异常处理");
e.printStackTrace();
}
}
}
}
二、再看看class
-
try-with-resource的写法编译后的class,由此可见,编译器自动生成了try-finally的结构
public static void main(String[] args) {
try {
FileOutputStream fileOutputStream = new FileOutputStream("text.txt");
Throwable var2 = null;
try {
System.out.println("文件写入开始");
fileOutputStream.write(1);
System.out.println("文件写入完成");
} catch (Throwable var12) {
var2 = var12;
throw var12;
} finally {
if (fileOutputStream != null) {
if (var2 != null) {
try {
fileOutputStream.close();
} catch (Throwable var11) {
var2.addSuppressed(var11);
}
} else {
fileOutputStream.close();
}
}
}
} catch (IOException var14) {
System.out.println("异常处理开始");
var14.printStackTrace();
System.out.println("异常处理完成");
}
}
-
try-with-resource中的异常处理
由上段代码可见
1.当 fileOutputStream.write(1)抛出异常var12时,fileOutputStream.close()也抛出异常var11,会调用var12.addSuppressed(var11),在var12中记录下var11,然后抛出var12。(jdk1.7 Throwable中新增的suppressedExceptions,控制、抑制异常列表)
2.当 fileOutputStream.write(1)抛出异常var12时,fileOutputStream.close()正常,抛出var12。
3.当 fileOutputStream.write(1)正常时,fileOutputStream.close()抛出异常在finally未处理,则抛出流关闭的异常。
很多程序猿习惯吞掉流关闭的异常,在try-with-resource中就做不到了,如异常处理3中的情况。如使用try-with-resource方式关闭流,写代码的时候需要对流的使用异常及关闭异常一起做处理才可以。
三、AutoCloseable
jdk1.7增加了AutoCloseable类,且Closeable直接继承了AutoCloseable,之前继承了Closeable的流,在jdk1.7只有都支持try-with-resource的写法
/**
* 实现了AutoCloseable的类,MyAutoCloseable
*/
public class MyAutoCloseable implements AutoCloseable{
public void printStr(String str){
System.out.println("输出:"+str);
}
@Override
public void close() throws Exception {
System.out.println("流自动关闭了");
}
}
/**
* main 测试
*/
public class AutoCloseableTest {
public static void main(String[] args) {
try(MyAutoCloseable closeable = new MyAutoCloseable()) {
closeable.printStr("abc");
}catch (Exception e){
System.out.println("异常处理"+e);
}
}
}
执行输出结果:
输出:abc
流自动关闭了