今天看代码看到了有使用AutoCloseable接口,很好奇它的实现方式,以及在一个try里使用多个的时候他们关闭的先后顺序是怎么样的。
写了个例子,然后反编出来看了下,原来是在编译时候自动加入了close的调用,调用的顺序是写再后面的先close
验证代码:
public class AutoCloseableDemo {
static class MyAutoCloseable1 implements AutoCloseable{
@Override
public void close() {
System.out.println("MyAutoCloseable1 close");
}
public void doSomething(){
System.out.println("MyAutoCloseable1 doSomething");
}
}
static class MyAutoCloseable2 implements AutoCloseable{
@Override
public void close() {
System.out.println("MyAutoCloseable2 close");
}
public void doSomething(){
System.out.println("MyAutoCloseable2 doSomething");
}
}
public static void main(String args[]) throws InterruptedException {
try(
MyAutoCloseable1 mc1 = new MyAutoCloseable1();
MyAutoCloseable2 mc2 = new MyAutoCloseable2();
) {
mc1.doSomething();
mc2.doSomething();
}
}
}
反编出来的代码如下:
Compiled from "AutoCloseableDemo.java"
public class AutoCloseableDemo {
public AutoCloseableDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.InterruptedException;
Code:
0: new #2 // class AutoCloseableDemo$MyAutoCloseable1
3: dup
4: invokespecial #3 // Method AutoCloseableDemo$MyAutoCloseable1."<init>":()V
7: astore_1
8: aconst_null
9: astore_2
10: new #4 // class AutoCloseableDemo$MyAutoCloseable2
13: dup
14: invokespecial #5 // Method AutoCloseableDemo$MyAutoCloseable2."<init>":()V
17: astore_3
18: aconst_null
19: astore 4
21: aload_1
22: invokevirtual #6 // Method AutoCloseableDemo$MyAutoCloseable1.doSomething:()V
25: aload_3
26: invokevirtual #7 // Method AutoCloseableDemo$MyAutoCloseable2.doSomething:()V
29: aload_3
30: ifnull 110
33: aload 4
35: ifnull 57
38: aload_3
39: invokevirtual #8 // Method AutoCloseableDemo$MyAutoCloseable2.close:()V
42: goto 110
45: astore 5
47: aload 4
49: aload 5
51: invokevirtual #10 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
54: goto 110
57: aload_3
58: invokevirtual #8 // Method AutoCloseableDemo$MyAutoCloseable2.close:()V
61: goto 110
64: astore 5
66: aload 5
68: astore 4
70: aload 5
72: athrow
73: astore 6
75: aload_3
76: ifnull 107
79: aload 4
81: ifnull 103
84: aload_3
85: invokevirtual #8 // Method AutoCloseableDemo$MyAutoCloseable2.close:()V
88: goto 107
91: astore 7
93: aload 4
95: aload 7
97: invokevirtual #10 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
100: goto 107
103: aload_3
104: invokevirtual #8 // Method AutoCloseableDemo$MyAutoCloseable2.close:()V
107: aload 6
109: athrow
110: aload_1
111: ifnull 181
114: aload_2
115: ifnull 134
118: aload_1
119: invokevirtual #11 // Method AutoCloseableDemo$MyAutoCloseable1.close:()V
122: goto 181
125: astore_3
126: aload_2
127: aload_3
128: invokevirtual #10 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
131: goto 181
134: aload_1
135: invokevirtual #11 // Method AutoCloseableDemo$MyAutoCloseable1.close:()V
138: goto 181
141: astore_3
142: aload_3
143: astore_2
144: aload_3
145: athrow
146: astore 8
148: aload_1
149: ifnull 178
152: aload_2
153: ifnull 174
156: aload_1
157: invokevirtual #11 // Method AutoCloseableDemo$MyAutoCloseable1.close:()V
160: goto 178
163: astore 9
165: aload_2
166: aload 9
168: invokevirtual #10 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
171: goto 178
174: aload_1
175: invokevirtual #11 // Method AutoCloseableDemo$MyAutoCloseable1.close:()V
178: aload 8
180: athrow
181: return
Exception table:
from to target type
38 42 45 Class java/lang/Throwable
21 29 64 Class java/lang/Throwable
21 29 73 any
84 88 91 Class java/lang/Throwable
64 75 73 any
118 122 125 Class java/lang/Throwable
10 110 141 Class java/lang/Throwable
10 110 146 any
156 160 163 Class java/lang/Throwable
141 148 146 any
}