2

想想这个示例代码:

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

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

在这里,我想复制 try 块的字节码(可能使用 ASM),对字节码进行一些修改(例如用 stm4 替换 stm2)并在 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

以下是迄今为止最简单的

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

您也可以使用 ASM 执行您的建议。但是,您采用的几乎任何替代方法都可能更简单。当您几乎无法控制正在运行的代码(或很少控制性能)时,ASM 通常是最佳选择。我假设您对代码有一定的控制权。

于 2011-09-07T15:28:43.653 回答
0

您可以将这些单独的语句分解为单独的方法或类,并使用 Java 反射来调用单独的语句。然后由您决定以什么顺序通过这些反射调用进行迭代。

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

于 2011-09-07T18:41:10.113 回答
0

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

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

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

于 2011-09-07T15:31:02.820 回答