使用Objecweb ASM在Java中为静态字段创建getter

时间:2015-05-12 08:54:40

标签: java static return getter java-bytecode-asm

好吧,我试图在ClassA中创建一个getter,它使用Objectweb ASM在ClassB中返回一个静态字段。 我开始的课程看起来像这样:

ClassA的:

public class ClassA {

}

ClassB的:

public class ClassB {

    static int secret = 123;

}

我尝试将ClassA转换为反编译后的样子:

public class ClassA {

    public int getSecretInt(){
        return ClassB.secret;
    }
}

到目前为止,我已经能够返回ClassA内部的字段,但我不确定如何在其他类中返回静态字段。

我能做什么:(这为ClassA添加了一个方法,在其自身内部返回一个变量)

        MethodNode mn = new MethodNode(ACC_PUBLIC, getterName, "()" + fieldDescriptor, signature, null);

        mn.instructions.add(new VarInsnNode(ALOAD, 0));
        mn.instructions.add(new FieldInsnNode(isStatic ? GETSTATIC : GETFIELD, cn.name, fieldName, fieldDescriptor));
        mn.instructions.add(new InsnNode(retInsn));

        mn.visitMaxs(3, 3);
        mn.visitEnd();
        cn.methods.add(mn);

我想要做的是让我生成的这个方法从ClassB返回一个静态值。

基本上成功:

return ClassB.secret;

1 个答案:

答案 0 :(得分:0)

通常,获取对ASM的正确调用的最简单方法是在从某些Java代码编译的字节码(.class文件)上使用ASMifier类。

也就是说,从另一个类获取静态字段很简单,不需要使用ASMifier。假设你有一个从ClassWriter获得的MethodVisitor mw(如果你想直接生成字节码),它看起来像:

mw.visitFieldInsn(Opcodes.GETSTATIC, "ClassB", "secret", "I");
mw.visitInsn(Opcodes.IRETURN);

无需加载"这个" (ALOAD 0)。此外,您不必自己计算帧和本地,您可以使用ClassWriter.COMPUTE_FRAMES和COMPUTE_MAXS,以便ASM为您完成。对于你展示的代码,你只有一个变量("这个"是隐含的),只需要一个堆栈元素(对于ClassB.secret的值)。