Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 执行一段字节码_Java_Bytecode_Bytecode Manipulation - Fatal编程技术网

Java 执行一段字节码

Java 执行一段字节码,java,bytecode,bytecode-manipulation,Java,Bytecode,Bytecode Manipulation,请考虑以下示例代码: ... try { stm1 stm2 stm3 } catch(){ ... } ... 假设要运行代码,在try块中引发异常。执行流进入catch块 在这里,我想复制try块的字节码(可能使用ASM),对字节码应用一些修改(例如用stm4替换stm2),并在catch块中执行新的字节码 这是否可能不编译或加载新字节码,而只是像解释语言一样执行它 谢谢大家! 更新 我知道我可以事先编写正确的代码。问题不在于为什么,而在于如何做到这一点,以

请考虑以下示例代码:

...
try {
    stm1
    stm2
    stm3
} catch(){
    ...
}
...
假设要运行代码,在try块中引发异常。执行流进入catch块

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

这是否可能不编译或加载新字节码,而只是像解释语言一样执行它

谢谢大家!

更新 我知道我可以事先编写正确的代码。问题不在于为什么,而在于如何做到这一点,以及如果可能的话


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

以下是迄今为止最简单的

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

你也可以用ASM做你建议的事情。然而,几乎所有您采取的替代方法都可能更简单。当您对正在运行的代码几乎没有控制权(或很少对性能有控制权)时,ASM通常是最好的选择。我假设您对代码有一定的控制权。

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

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


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

您最好设置一个状态机并动态确定下一个状态。比如:

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;
    }
}

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


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

您希望实现什么?我们在一个确定性的世界里,为什么要执行一些已经再次失败的东西?为什么不编写要运行的不同代码?为什么特别关心字节码?您试图实现的更大目标是什么?您可以在catch块中执行
{stm1;stm4;stm3}
。这不需要ASM。如果你能用为什么需要使用ASM的信息更新你的问题,你的问题会更有意义。@Niko:如果你能提供一个有意义的例子,我打赌你会得到更好的答案。谢谢。但是让我们假设它必须动态地计算序列stm1,stm4,stm3,所以我不能在源代码中写它,它必须写在某个地方。根据您从何处获得它(以及以何种形式)确定哪种是最简单的解决方案。我可以在哪里编写它?我如何执行它。考虑一下代码应该很容易访问局部变量和类变量。当您编写字节码时,它是针对整个类的。(即使该类只有一个方法)如果您想轻松访问字段,它们必须是非私有的,或者您必须重写整个类。有关如何使用ASM编写字节码的示例,请参阅ASM文档。一旦你将字节码设置为byte[],你就可以使用defineClass加载它。所以,没有办法只执行从同一个类中提取的字节码,对吗?(就像在python中执行一系列代码)