java 8 try关闭流_java8学习第二篇:try-with-resources

Java8里的一个新语法特性:try-with-resources。

这个语法特性其实从java7里就有了,不过java8的sample里依然有这个。

try-with-resources的特性就是,在try( …)里声明的资源,会在try-catch代码块结束后自动关闭掉。

废话不说,先上代码后分析。

public class AutoCloseTest {

public static void main(String[] args) {

testNormalOutput(args[0]);

testAutoCloseWithTryCatch(args[1]);

}

private static void testNormalOutput(String filepath){

OutputStream global_out = null;

BufferedWriter writer ;

try {

OutputStream out = out = new FileOutputStream(filepath);

global_out = out;

out.write((filepath + "inside try catch block").getBytes());

} catch (Exception e) {

e.printStackTrace();

}

try{

if(global_out!=null){

global_out.write(" \t\r outside try catch block".getBytes());

global_out.close();

}

} catch (Exception e){

e.printStackTrace();

}

}

private static void testAutoCloseWithTryCatch(String filepath){

OutputStream global_out = null;

try(OutputStream out = new FileOutputStream(filepath);) {

global_out = out;

out.write((filepath+"inside try catch block").getBytes());

} catch (Exception e) {

e.printStackTrace();

}

try{

if(global_out!=null){

global_out.write(" \t\r outside try catch block".getBytes());

global_out.close();

}

} catch (Exception e){

e.printStackTrace();

}

}

}

运行

java AutoCloseTest d:/a.txt d:/b.txt

然后发现

a.txt里的内容是

d:/a.txt inside try catch block outside try catch block

b.txt里的内容是

d:/b.txt inside try catch block

没错,b.txt的后半段代码没有执行 同时控制台还打印出

java.io.IOException: Stream Closed

at java.io.FileOutputStream.writeBytes(Native Method)

at java.io.FileOutputStream.write(FileOutputStream.java:294)

at trywithresources.AutoCloseTest.testAutoCloseWithTryCatch(AutoCloseTest.java:46)

at trywithresources.AutoCloseTest.main(AutoCloseTest.java:11)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

这是因为在testAutoCloseWithTryCatch方法里,global_out所指向的out对象已经在第一次try-catch之后被关闭了 在第二次对这个已经关闭的流里输出内容时,就会报Stream Closed错误。

——————–*************************———————–********************

那么try-with-resources是如何工作的呢?它和finally的工作谁在前呢?我们可以做一个小测试

private static void testAutoClose() {

AutoCloseable global_obj1 = null;

AutoCloseable global_obj2 = null;

try(AutoCloseable obj1 = new AutoClosedImpl("obj1");

AutoCloseable obj2 = new AutoClosedImpl("obj2");){

global_obj1= obj1;

int i = 1/0;

global_obj2= obj2;

} catch (Exception e) {

e.printStackTrace();

}finally{

try{

System.out.println("before finally close");

if(global_obj1!=null){

global_obj1.close();

}

if(global_obj2!=null){

global_obj2.close();

}

System.out.println("after finally close");

} catch(Exception e){

e.printStackTrace();

}

}

}

private static class AutoClosedImpl implements AutoCloseable{

private String name;

public AutoClosedImpl(String name){

this.name = name;

}

@Override

public void close() throws Exception {

System.out.println(name+" closing");

}

}

执行testAutoClose()方法,会打印出如下结果

obj2 closing

obj1 closing

before finally close

obj1 closing

after finally close

java.lang.ArithmeticException: / by zero

at trywithresources.AutoCloseTest.testAutoClose(AutoCloseTest.java:60)

at trywithresources.AutoCloseTest.main(AutoCloseTest.java:12)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:483)

at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

从上述代码我们可以观测四件事 1. 凡是实现了AutoCloseable接口的类,在try()里声明该类实例的时候,在try结束后,close方法都会被调用 2. try结束后自动调用的close方法,这个动作会早于finally里调用的方法。 3. 不管是否出现异常(int i=1/0会抛出异常),try()里的实例都会被调用close方法 4. 越晚声明的对象,会越早被close掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值