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


}

methodmainには、2 つの例外エントリ ポイント (「ターゲット」) があります: 6 と 9。6 に続いて、athrowオフセット 8 があります。エントリ ポイント 9 に続いて、athrowオフセット 18 があります。

于 2013-08-23T23:06:31.667 に答える