2

次のサンプル コードについて考えてみましょう。

...
try {
    stm1
    stm2
    stm3
} catch(){
    ...
}
...

コードを実行すると、try ブロック内で例外が発生したとします。実行フローは catch ブロックに入ります。

ここで、try ブロックのバイトコードを (おそらく ASM を使用して) コピーし、バイトコードにいくつかの変更を適用し (たとえば、stm2 を stm4 に置き換える)、catch ブロック内で新しいバイトコードを実行します。

これは、新しいバイトコードをコンパイルまたはロードせずに、インタープリター言語のように実行するだけで可能ですか?

ありがとうございました!

アップデート

アプリオリに適切なコードを記述できることを知っています。問題は理由ではなく、それを行う方法と可能かどうかです。

新しい try 本体を動的に計算する必要があり、同じオブジェクト内で新しいコードを実行する必要があるとします (ローカル変数とクラス変数のため)。

4

4 に答える 4

1

おそらく、ステート マシンをセットアップして、次の状態を動的に決定する方がよいでしょう。何かのようなもの:

int nextState = 0;
while(nextState != -1) {
    try {
        switch(nextState) {
            case 0:
                stm1;
                ++nextState;
                break;
             case 1:
                stm2;
                ++nextState;
                break;
             case 2:
                stm3;
                nextState = -1;
                break;
             case 3:
                stm4;
                nextState = 2;
                break;
        }
    } catch (Exception err) {
        nextState = 3;
    }
}
于 2011-09-07T15:54:51.913 に答える
0

これらの個々のステートメントを個別のメソッドまたはクラスに分解し、Javaリフレクションを使用して個々のステートメントを呼び出すことができます。次に、これらのリフレクティブコールをどの順序で繰り返すかはあなた次第です。

もう1つのオプションは、コードを動的に生成し、BeanShell、Groovy、JavaScript/RhinoなどのJVMでサポートされているスクリプト言語の1つを使用して実行することです。

于 2011-09-07T18:41:10.113 に答える
0

以下は、はるかに簡単です

try {
    stm1
    stm2
    stm3
} catch(){
    stm1
    stm4 // instead of stm2
    stm3
}

ASMでも提案したことを行うことができます。ただし、ほとんどの代替アプローチは、より単純である可能性があります。ASM は通常、実行しているコードをほとんど制御できない場合 (またはパフォーマンスがほとんどない場合) に最適なオプションです。コードをある程度制御できると思います。

于 2011-09-07T15:28:43.653 に答える
0

バイトコードソリューションではなく、Java :)

catch ステートメントにロジックを入力するだけで、問題を解決できる場合があります。1 つの欠点は、try catch ブロックがそれぞれの内部にネストされ、見栄えが悪いことです。

しかし、バイトコードをロードするよりもメンテナンスしやすいと思います。

于 2011-09-07T15:31:02.820 に答える