想想这个示例代码:
...
try {
stm1
stm2
stm3
} catch(){
...
}
...
假设运行代码并在try块中引发异常。执行流程进入catch块。
在这里,我想复制try块的字节码(可能使用ASM),对字节码应用一些修改(例如用stm4替换stm2)并在catch块中执行新的字节码。
这是否可以在不编译或加载新字节码的情况下实现,只是像解释语言一样执行它?
谢谢!
我知道我可以先验地编写正确的代码。问题不是为什么,而是如何做到这一点以及是否有可能。
假设我必须动态计算新的try体,并且我必须在同一个对象中执行新代码(因为局部变量和类变量。)
答案 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等。