【发布时间】:2014-03-23 16:13:48
【问题描述】:
Java 代码如下所示:
File f1 = File.createTempFile("example", ".txt");
File f2 = File.createTempFile("outExample", ".txt");
FileInputStream in = new FileInputStream(f1);
FileOutputStream out = new FileOutputStream(f2);
try {
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
return f1.delete() && f2.delete();
以及为此的字节码:
TRYCATCHBLOCK L0 L1 L1
L2
LINENUMBER 138 L2
LDC "example"
LDC ".txt"
INVOKESTATIC File.createTempFile (String, String) : File
ASTORE 1
L3
LINENUMBER 139 L3
LDC "outExample"
LDC ".txt"
INVOKESTATIC File.createTempFile (String, String) : File
ASTORE 2
L4
LINENUMBER 141 L4
NEW FileInputStream
DUP
ALOAD 1: f1
INVOKESPECIAL FileInputStream.<init> (File) : void
ASTORE 3
L5
LINENUMBER 142 L5
NEW FileOutputStream
DUP
ALOAD 2: f2
INVOKESPECIAL FileOutputStream.<init> (File) : void
ASTORE 4
L0
LINENUMBER 146 L0
GOTO L6
L7
LINENUMBER 147 L7
ALOAD 4: out
ILOAD 5: c
INVOKEVIRTUAL FileOutputStream.write (int) : void
L6
LINENUMBER 146 L6
ALOAD 3: in
INVOKEVIRTUAL FileInputStream.read () : int
DUP
ISTORE 5
L8
ICONST_M1
IF_ICMPNE L7
L9
LINENUMBER 149 L9
GOTO L10
L1
LINENUMBER 150 L1
ASTORE 6
L11
LINENUMBER 151 L11
ALOAD 3: in
IFNULL L12
L13
LINENUMBER 152 L13
ALOAD 3: in
INVOKEVIRTUAL FileInputStream.close () : void
L12
LINENUMBER 154 L12
ALOAD 4: out
IFNULL L14
L15
LINENUMBER 155 L15
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void
L14
LINENUMBER 157 L14
ALOAD 6
ATHROW
L10
LINENUMBER 151 L10
ALOAD 3: in
IFNULL L16
L17
LINENUMBER 152 L17
ALOAD 3: in
INVOKEVIRTUAL FileInputStream.close () : void
L16
LINENUMBER 154 L16
ALOAD 4: out
IFNULL L18
L19
LINENUMBER 155 L19
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void
L18
LINENUMBER 159 L18
ALOAD 1: f1
INVOKEVIRTUAL File.delete () : boolean
IFEQ L20
ALOAD 2: f2
INVOKEVIRTUAL File.delete () : boolean
IFEQ L20
ICONST_1
IRETURN
L20
ICONST_0
IRETURN
谁能告诉我为什么每个流(L13 和 L17、L15 和 L19)调用两次 close() 指令?如果没有 finally 块,但使用 try-catch,则字节码中的每个流只调用一个 close()。
【问题讨论】:
-
我看到两个
close电话。 -
@ThomasJungblut 肯定有 4 个。
-
除此之外:finally-close 模式被打破了。如果第一次关闭抛出异常(不要忘记运行时异常),第二次将永远不会被调用。
-
@SotiriosDelimanolis 有这样的东西:“所以如果语句0-9之间发生任何异常,请转到第20行并在goto之后执行finally中的所有内容。如果没有发生异常,则执行finally 然后执行 goto,在 goto 之后跳过 finally。”在我的情况下没有发生异常,那么为什么 finally 出现两次?也许我没有正确理解。