gpt4 book ai didi

java - 为什么java字节码中有些指令会重复?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:47:21 25 4
gpt4 key购买 nike

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 block ,但使用 try-catch,字节码中的每个流只会调用一个 close()。

最佳答案

Ones 适用于异常被隐式捕获并需要重新抛出的情况(注意末尾的 ATHROW)

L15
LINENUMBER 155 L15
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void
L14
LINENUMBER 157 L14
ALOAD 6
ATHROW

另一个用于没有抛出异常的情况:

L19
LINENUMBER 155 L19
ALOAD 4: out
INVOKEVIRTUAL FileOutputStream.close () : void

如果你往上看,你会看到

TRYCATCHBLOCK L0 L1 L1 

这些标签类似于跳到哪里 catch 和跳到哪里。 Catch 将抛出的异常留在堆栈顶部(同样是 ATHROW)。检查堆栈以查看顶部成员是否是异常比仅复制代码要昂贵得多(而且更难/不可能;堆栈没有类型化)。

关于java - 为什么java字节码中有些指令会重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22593441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com