使用ASM 框架为类动态增加属性

  有一个测试类Demo.class,现在需要给这个类增加一个属性private String name

public class Demo{
}

  增加属性的方式:

package test;

import org.objectweb.asm.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import static org.objectweb.asm.Opcodes.ASM5;


public class AddField extends ClassVisitor {

    private String name;
    private int access;
    private String desc;
    private Object value;

    private boolean duplicate;

    // 构造器
    public AddField(ClassVisitor cv, String name, int access, String desc, Object value) {
        super(ASM5, cv);
        this.name = name;
        this.access = access;
        this.desc = desc;
        this.value = value;
    }

    @Override
    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        if (this.name.equals(name)) {
            duplicate = true;
        }
        return super.visitField(access, name, desc, signature, value);
    }

    @Override
    public void visitEnd() {
        if (!duplicate) {
            FieldVisitor fv = super.visitField(access, name, desc, null, value);
            if (fv != null) {
                fv.visitEnd();
            }
        }
        super.visitEnd();
    }

    public static void main(String[] args) throws Exception {
        String classDir="/Users/xule05/test/testasm/src/main/java/test/Demo.class";
        String output = "/Users/xule05/test/testasm/src/main/java/test/";
        ClassReader classReader = new ClassReader(new FileInputStream(classDir));
        ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
        ClassVisitor addField = new AddField(classWriter,
                "field",
                Opcodes.ACC_PRIVATE ,
                Type.getDescriptor(String.class),
                "demo"
        );
        classReader.accept(addField, ClassReader.EXPAND_FRAMES);
        byte[] newClass = classWriter.toByteArray();
        File newFile = new File(output, "NewDemo.class");
        new FileOutputStream(newFile).write(newClass);
    }
}

  上述给类增加属性的代码是一般的格式,并且在ASM的其他包中都有类似的代码,来源于一个通用的模板。
  输出的类反编译的结果如下:


使用ASM 框架为类动态增加属性_第1张图片
Demo.class

  ASM 非常容易的实现了为已知的类增加新的属性。增加方法或者代码块等都是类似的。

你可能感兴趣的:(使用ASM 框架为类动态增加属性)