1、Person2.java
package com.study.asm;
public class Person2 {
public String name = "yuanyi";
public String address = "bj";
}
为上述类添加一个age属性:
package com.study.asm;
import java.io.File;
import java.io.FileOutputStream;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
public class AddOneField {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
ClassReader classReader = new ClassReader("com.study.asm.Person2");
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassAdapter adapter = new MyClassAdapter2(classWriter);
classReader.accept(adapter, ClassReader.SKIP_DEBUG);
byte[] buf = classWriter.toByteArray();
GeneratorClassLoader classLoader = new GeneratorClassLoader ();
Class clazz = classLoader.defineClassFromClassFile("com.study.asm.Person2", buf);
Object obj = clazz.newInstance();
// System.out.println(clazz.getDeclaredField("name").get(obj));
System.out.println(clazz.getDeclaredField("age").get(obj));
File file = new File("D://Person2.class");
FileOutputStream fos = new FileOutputStream(file);
fos.write(buf);
fos.close();
}
}
class MyClassAdapter2 extends ClassAdapter{
public MyClassAdapter2(ClassVisitor cv) {
super(cv);
}
@Override
public void visitEnd() {
cv.visitField(Opcodes.ACC_PUBLIC, "age", Type.getDescriptor(int.class), null, null);
}
/*
* 调用此方法会重复添加age属性,会报错
* 具体原因参看:http://victorzhzh.iteye.com/blog/882699
* @Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
cv.visitField(Opcodes.ACC_PUBLIC, "age", Type.getDescriptor(int.class), null, null);
return super.visitField(access, name, desc, signature, value);
}*/
}
class GeneratorClassLoader extends ClassLoader {
@SuppressWarnings("rawtypes")
public Class defineClassFromClassFile(String className, byte[] classFile)throws Exception{
return defineClass(className, classFile, 0, classFile.length);
}
}
3、结果
反编译后,得到如下结果:
package com.study.asm;
public class Person2
{
public String name = "yuanyi";
public String address = "bj";
public int age;
}