我想检测catch块中发生的throw语句。例如:
try
{
def();
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
首先,我使用Eclipse-JDT来检测这些情况,这非常简单,因为我可以遍历抽象语法树。
现在我必须使用直接处理字节码的框架(BAT - 字节码分析工具包)。
首先,如何在字节码中表示catch块?如何在其中检测throw语句?
答案 0 :(得分:3)
每个方法都有一个异常表,它将一系列指令加上异常类型映射到异常处理程序(它的入口点)。这并不总是很容易转换回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之后,我们在偏移8处有athrow
。在9的入口点之后,我们有偏移量为18的athrow
。就是这样!