美文网首页ASM 字节码框架源码解析
使用ASM 框架为类动态增加属性

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

作者: Xcdf | 来源:发表于2019-02-06 22:02 被阅读6次

      有一个测试类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的其他包中都有类似的代码,来源于一个通用的模板。
      输出的类反编译的结果如下:


    Demo.class

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

    相关文章

      网友评论

        本文标题:使用ASM 框架为类动态增加属性

        本文链接:https://www.haomeiwen.com/subject/pfgisqtx.html