Java 8里面的「try-with-resources clause」和「Autoclosable」接口
在Java 8里面引入了「Autoclosable」接口,关于这个接口和「try-with-resources clause」的详细用法,可以查看这篇文档1,本文简单记录它的使用方法。
public class FooClass implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("close() method called");
}
}
public class PlayWithAutoclosable {
public static void main(String[] args) {
try (FooClass foo = new FooClass()) {
// use the FooClass instance here.
System.out.println(foo);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如上代码所示,我们创建了一个「FooClass」,它实现了「AutoCloseable」接口,这个接口定义一个「close()」方法,会在「try-with-resources clause」执行结束后被自动调用,等于代替了原有的「finally clause」。
第二个「PlayWithAutoclosable」展示了如何在「try-with-resources clause」里面使用第一个「FooClass」。执行这个class的main方法,结果如下:
lang.PlayWithAutoclosable$FooClass@4769b07b
close() method called
可以看到「close()」方法在「try-with-resources clause」执行完毕之后被自动执行了。
如果把编译后的「PlayWithAutoclosable」给解码成bytecodes,可以看到多处执行「close()」的calls:
$ javap -c ./target/classes/lang/autoclosable/PlayWithAutoclosable.class
Compiled from "PlayWithAutoclosable.java"
public class lang.autoclosable.PlayWithAutoclosable {
public lang.autoclosable.PlayWithAutoclosable();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class lang/autoclosable/FooClass
3: dup
4: invokespecial #3 // Method lang/autoclosable/FooClass."<init>":()V
7: astore_1
8: aconst_null
9: astore_2
10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: aload_1
18: ifnull 88
21: aload_2
22: ifnull 41
25: aload_1
26: invokevirtual #6 // Method lang/autoclosable/FooClass.close:()V
29: goto 88
32: astore_3
33: aload_2
34: aload_3
35: invokevirtual #8 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
38: goto 88
41: aload_1
42: invokevirtual #6 // Method lang/autoclosable/FooClass.close:()V
45: goto 88
48: astore_3
49: aload_3
50: astore_2
51: aload_3
52: athrow
53: astore 4
55: aload_1
56: ifnull 85
59: aload_2
60: ifnull 81
63: aload_1
64: invokevirtual #6 // Method lang/autoclosable/FooClass.close:()V
67: goto 85
70: astore 5
72: aload_2
73: aload 5
75: invokevirtual #8 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
78: goto 85
81: aload_1
82: invokevirtual #6 // Method lang/autoclosable/FooClass.close:()V
85: aload 4
87: athrow
88: goto 96
91: astore_1
92: aload_1
93: invokevirtual #10 // Method java/lang/Exception.printStackTrace:()V
96: return
Exception table:
from to target type
25 29 32 Class java/lang/Throwable
10 17 48 Class java/lang/Throwable
10 17 53 any
63 67 70 Class java/lang/Throwable
48 55 53 any
0 88 91 Class java/lang/Exception
}
如上所示,编译后的代码在多处都有「FooClass.close()」的痕迹,其实就是保证在多处Throwable和Exception发生后,最终都会call到「close()」方法,实际上就是「finally」的作用。
-
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html ↩
- 上一篇 试玩opentracing-walkthrough
- 下一篇 日语学习笔记・14