1.实体类
- package com.study.asm;
- public class Person {
- private String name;
- public void sayName(){
- System.out.println(name);
- }
- }
2.Client
- 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.MethodAdapter;
- import org.objectweb.asm.MethodVisitor;
- import org.objectweb.asm.Opcodes;
- import org.objectweb.asm.Type;
- public class GenerateNewPerson {
- public static void main(String[] args) throws Exception{
- // 使用全限定名,创建一个ClassReader对象
- ClassReader classReader = new ClassReader("com.study.asm.Person");
- // 构建一个ClassWriter对象,并设置让系统自动计算栈和本地变量大小
- ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- ClassAdapter classAdapter = new GeneralClassAdapter(classWriter);
- classReader.accept(classAdapter, ClassReader.SKIP_DEBUG);
- byte[] classFile = classWriter.toByteArray();
- File file = new File("D://Person.class");
- FileOutputStream fos = new FileOutputStream(file);
- fos.write(classFile);
- fos.close();
- }
- }
- class GeneralClassAdapter extends ClassAdapter{
- public GeneralClassAdapter(ClassVisitor cv) {
- super(cv);
- }
- @Override
- public MethodVisitor visitMethod(int access, String name, String desc,
- String signature, String[] exceptions) {
- MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
- // 当是sayName方法是做对应的修改
- if(name.equals("sayName")){
- MethodVisitor newMv = new sayNameMethodAdapter(mv);
- return newMv;
- }else{
- return mv;
- }
- }
- // 定义一个自己的方法访问类
- class sayNameMethodAdapter extends MethodAdapter{
- public sayNameMethodAdapter(MethodVisitor mv) {
- super(mv);
- }
- // 在源方法前去修改方法内容,这部分的修改将加载源方法的字节码之前
- @Override
- public void visitCode() {
- // 记载隐含的this对象,这是每个JAVA方法都有的
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- // 从常量池中加载“yy”字符到栈顶
- mv.visitLdcInsn("yy");
- // 将栈顶的"yy"赋值给name属性
- mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(Person.class), "name", Type.getDescriptor(String.class));
- }
- }
- }
3.结果
通过jd-gui反编译后,得到的结果如下:
- package com.study.asm;
- import java.io.PrintStream;
- public class Person
- {
- private String name;
- public void sayName()
- {
- this.name = "yy";
- System.out.println(this.name);
- }
- }
通过javap -c Person命令,得到如下结果:
- public class com.study.asm.Person extends java.lang.Object{
- public com.study.asm.Person();
- Code:
- 0: aload_0
- 1: invokespecial #10; //Method java/lang/Object."<init>":()V
- 4: return
- public void sayName();
- Code:
- 0: aload_0
- 1: ldc #13; //String yy
- 3: putfield #15; //Field name:Ljava/lang/String;
- 6: getstatic #21; //Field java/lang/System.out:Ljava/io/PrintStream;
- 9: aload_0
- 10: getfield #15; //Field name:Ljava/lang/String;
- 13: invokevirtual #27; //Method java/io/PrintStream.println:(Ljava/lang/St
- ring;)V
- 16: return
- }