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

Creating a getter for a static field in Java using Objecweb ASM

好的,所以我正在尝试使用 Objectweb ASM 在 ClassA 中创建一个 getter,return 是 ClassB 中的一个静态字段。 我开始的 类 看起来像这样:

A 类:

public class ClassA {

}

B 类:

public class ClassB {

    static int secret = 123;

}

我正在尝试将 ClassA 转储为反编译后的样子:

public class ClassA {

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

到目前为止,我已经能够 return ClassA 内部的字段,但我不确定如何在其他 类.[=17 中处理 returning 静态字段=]

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

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

我想要做的是让这个方法生成 return 来自 ClassB 的静态值。

基本上做到了:

return ClassB.secret;

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

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

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

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