编译这个小程序(我意识到我应该使用你的例子,但这没有任何影响)
public static void main(String[] args) {
try {
Float s = Float.parseFloat("0.0327f");
} finally {
System.out.println("hello");
}
}
我使用过
>java -version
java version "1.8.0-ea" // should be same for 7
Java(TM) SE Runtime Environment (build 1.8.0-ea-b118)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b60, mixed mode)
然后执行
javac -v -c <fully qualified class name>
获取字节码。你会看到类似这样的内容。
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: ldc
2: invokestatic
5: invokestatic
8: astore_1
9: getstatic
12: ldc
14: invokevirtual
17: goto 31
20: astore_2
21: getstatic
24: ldc
26: invokevirtual
29: aload_2
30: athrow
31: return
Exception table:
from to target type
0 9 20 any
20 21 20 any
LineNumberTable:
line 10: 0
line 12: 9
line 13: 17
line 12: 20
line 14: 31
StackMapTable: number_of_entries = 2
frame_type = 84 /* same_locals_1_stack_item */
stack = [ class java/lang/Throwable ]
frame_type = 10 /* same */
你会注意到在finally
中的代码出现了两次,一次是在goto
之前,一次是之后。你还会注意到Exception table
,它指定了如果在某行发生异常要去哪个语句。
因此,如果在语句0-9之间发生任何异常,则转到第20行并执行finally
中的所有内容,在goto
之后。如果没有发生异常,则先执行finally
,然后执行goto
跳过finally
之后的部分。
在所有情况下,您都将执行finally
块中的代码。
其他未明确处理的异常
使用finally
块,将创建一个Exception table
条目,用于处理任何类型的Throwable
。
这里是字节码指令清单。
finally
块会在通知ThreadGroup
之前被处理... - MadProgrammer