每个方法都有一个异常表,它将一系列指令以及异常类型映射到异常处理程序(它是入口点)。这并不总是很容易转换回 Java 代码。但一般来说,您需要检查此表,然后从这些入口点分析可访问的代码。所有这些代码都属于一个catch
子句。那么这只是识别athrow
指令的问题。
使用javap
或其他好的字节码可视化工具来玩转并更好地理解它。完成你的代码,编译它,然后让它javap
产生:
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void def() throws java.io.IOException;
Code:
0: new #2; //class java/io/IOException
3: dup
4: invokespecial #3; //Method java/io/IOException."<init>":()V
7: athrow
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: invokestatic #4; //Method def:()V
3: goto 19
6: astore_1
7: aload_1
8: athrow
9: astore_1
10: new #6; //class java/lang/RuntimeException
13: dup
14: aload_1
15: invokespecial #7; //Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V
18: athrow
19: return
Exception table:
from to target type
0 3 6 Class java/io/IOException
0 3 9 Class java/lang/Exception
}
对于方法main
,我们有 2 个异常入口点(“目标”):6 和 9。在 6 之后,我们有一个athrow
at offset 8。在入口点 9 之后,我们有一个athrow
at offset 18。就是这样!