由 Sun 的 javac 生成的奇怪的异常表条目
给定此程序:
class Test {
public static void main(String[] args) {
try {
throw new NullPointerException();
} catch (NullPointerException npe) {
System.out.println("In catch");
} finally {
System.out.println("In finally");
}
}
}
Sun 的 (v 1.6.0_24) 产生以下字节码:javac
public static void main(java.lang.String[]);
// Instantiate / throw NPE
0: new #2; // class NullPointerException
3: dup
4: invokespecial #3; // Method NullPointerException."<init>":()V
7: athrow
// Start of catch clause
8: astore_1
9: getstatic #4; // Field System.out
12: ldc #5; // "In catch"
14: invokevirtual #6; // Method PrintStream.println
17: getstatic #4; // Field System.out
// Inlined finally block
20: ldc #7; // String In finally
22: invokevirtual #6; // Method PrintStream.println
25: goto 39
// Finally block
// store "incomming" exception(?)
28: astore_2
29: getstatic #4; // Field System.out
32: ldc #7; // "In finally"
34: invokevirtual #6; // Method PrintStream.println
// rethrow "incomming" exception
37: aload_2
38: athrow
39: return
但有以下例外表:
Exception table:
from to target type
0 8 8 Class NullPointerException
0 17 28 any
28 29 28 any
我的问题是:为什么它在异常表中包含最后一个条目?!
据我所知,它基本上是说“如果astore_2
抛出异常,抓住它,然后重试相同的指令”。
即使使用空的 try/catch/ finally 子句(例如
try {} catch (NullPointerException npe) {} finally {}
二. 一些意见
- Eclipse 编译器不会生成任何此类异常表条目
- JVM 规范不记录
astore
指令的任何运行时异常。 - 我知道JVM为任何指令抛出都是合法的。我猜这个奇特的条目可以防止任何此类错误从该指令中传播出去。
VirtualMachineError