1

我想检测从 catch 块中发生的 throw 语句。例如:

try 
{
    def();
}
catch (IOException e)
{
    throw e;
}
catch (Exception e)
{
    throw new RuntimeException(e);
}

首先,我使用 Eclipse-JDT 来检测这些情况,这非常简单,因为我可以遍历抽象语法树。

现在我必须使用一个直接处理字节码的框架(BAT - Bytecode Analysis Toolkit)。

首先,catch 块在字节码中是如何表示的?以及如何检测其中的 throw 语句?

4

1 回答 1

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 之后,我们有一个athrowat offset 8。在入口点 9 之后,我们有一个athrowat offset 18。就是这样!

于 2013-08-23T23:06:31.667 回答