假设我们使用 Java 6+ 编译器编译此方法:
void test(int x) {
try {
x += 777;
} finally {
x -= 333;
}
}
反汇编后的代码如下所示:
test(I)V
TRYCATCHBLOCK L0 L1 L2 null
TRYCATCHBLOCK L2 L3 L2 null
L0 // Start of try block
IINC 1 777 // The body of try block
L1 // Start of finally block in case of successful execution
IINC 1 -333 // Body of finally block
GOTO L4 // End of 'success' finally block
L2 // Start of finally block in case of exception
ASTORE 2 // Remember exception
L3
IINC 1 -333 // Duplicated body of finally block
ALOAD 2 // Load remembered exception
ATHROW // Rethrow the exception
L4 // End of try/finally
RETURN
L5
显然,这个声明指定了“try”部分和“finally”块的开头:
TRYCATCHBLOCK L0 L1 L2 null
但是下一个声明看起来很奇怪:
TRYCATCHBLOCK L2 L3 L2 null
为什么Java编译器在记住异常的同时保护它,为什么它递归地将自己指定为处理程序(即两个L2
s)?