有一个测试类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 非常容易的实现了为已知的类增加新的属性。增加方法或者代码块等都是类似的。
网友评论