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