执行一段字节码

时间:2011-09-07 15:19:39

标签: java bytecode bytecode-manipulation

想想这个示例代码:

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

假设运行代码并在try块中引发异常。执行流程进入catch块。

在这里,我想复制try块的字节码(可能使用ASM),对字节码应用一些修改(例如用stm4替换stm2)并在catch块中执行新的字节码。

这是否可以在不编译或加载新字节码的情况下实现,只是像解释语言一样执行它?

谢谢!

更新

我知道我可以先验地编写正确的代码。问题不是为什么,而是如何做到这一点以及是否有可能。

假设我必须动态计算新的try体,并且我必须在同一个对象中执行新代码(因为局部变量和类变量。)

4 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:0)

以下是迄今为止最简单的

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

您也可以按照ASM的建议行事。但是,您采取的几乎任何替代方法都可能更简单。当您无法控制正在运行的代码(或很少有性能)时,ASM通常是最佳选择。我认为您可以控制代码。

答案 2 :(得分:0)

不是字节码解决方案,而是Java:)

也许你可以通过在catch语句中输入逻辑来解决问题。一个缺点是try catch块将嵌套在每个内部并且看起来很难看。

但它认为字节码加载会更易于维护。

答案 3 :(得分:0)

您可以将这些单独的语句分解为单独的方法或类,并使用Java反射来调用单个语句。然后,你可以按照你通过这些反思性调用迭代的顺序来决定。

另一种选择是动态生成一段代码并使用JVM支持的一种脚本语言执行它,例如BeanShell,Groovy,JavaScript / Rhino等。