1 首先创建一个实体类Student. 代码如下
package com.org.xcyz.asm;
public class Student {
private int id;
private String name;
private boolean sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
2 然后准备添加字段age和setAge以及getAge方法
package com.org.xcyz.asm.trans;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.GETFIELD;
import static org.objectweb.asm.Opcodes.IRETURN;
import static org.objectweb.asm.Opcodes.PUTFIELD;
import static org.objectweb.asm.Opcodes.RETURN;
public class AddVisitorTransformer1 {
public static void main(String[] args) throws IOException {
String className = "com.org.xcyz.asm.Student";
String classJvmName = className.replace('.', '/');
ClassReader cr = new ClassReader(className);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM9,cw) {
boolean hasFiled = false;
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
if("age".equals(name) && "I".equals(descriptor))hasFiled=true;
return super.visitField(access, name, descriptor, signature, value);
}
@Override
public void visitEnd() {
if (!hasFiled) {
FieldVisitor fieldVisitor = cv.visitField(ACC_PRIVATE, "age", "I", null, null);
if (fieldVisitor != null) {
fieldVisitor.visitEnd();
}
MethodVisitor setAge = cv.visitMethod(ACC_PUBLIC, "setAge", "(I)V", null, null);
if (setAge != null) {
setAge.visitCode();
setAge.visitVarInsn(ALOAD,0);
setAge.visitVarInsn(ALOAD,1);
setAge.visitFieldInsn(PUTFIELD,classJvmName,"age","I");
setAge.visitInsn(RETURN);
setAge.visitEnd();
}
MethodVisitor getAge = cv.visitMethod(ACC_PUBLIC, "getAge", "()I", null, null);
if (getAge != null) {
getAge.visitCode();
getAge.visitVarInsn(ALOAD,0);
getAge.visitFieldInsn(GETFIELD,classJvmName,"age","I");
getAge.visitInsn(IRETURN);
getAge.visitEnd();
}
}
super.visitEnd();
}
};
cr.accept(classVisitor,ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
byte[] bytes = cw.toByteArray();
Files.write(Paths.get("target/classes/"+classJvmName+".class"),bytes,TRUNCATE_EXISTING,CREATE);
}
}
|