ASM是操作类字节码的工具包,提供ClassVisitor、FieldVisitor、MethodVisito等访问方法
public class AsmTest { public static void main(String[] args) throws Exception { b(); } public static void a() throws Exception{ String className = "classhandle.AsmClass"; String signature = "L" + className.replace(".", "/") + ";"; // 创建类,参数值为0,需要自己计算方法的局部变量表和操作数栈的大小,所以在创建方法时,需要调用方法的visitMaxs方法 //ClassWriter.COMPUTE_MAXS自动计算 ClassWriter classWriter = new ClassWriter(0); classWriter.visit(Opcodes.V1_8, 0x0001, className.replace(".", "/"), signature, Object.class.getName().replace(".", "/"), null); MethodVisitor methodVisitor = classWriter.visitMethod(0x0001," org.ow2.asm asm 6.2 ","()V",null,null); methodVisitor.visitCode(); // 调用父类构造器 methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL,"java/lang/Object"," ", "()V", false); // 添加一条返回指令 methodVisitor.visitInsn(Opcodes.RETURN); // 设置操作数栈和局部变量表大小 methodVisitor.visitMaxs(1,1); classWriter.visitEnd(); // 获取生成的class的字节数组 byte[] byteCode = classWriter.toByteArray(); File file = new File("D:\util\mypro\src\main\java\classhandle\" +className.substring(className.lastIndexOf(".")+1)+ ".class"); if ((!file.exists() || file.delete()) && file.createNewFile()) { try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(byteCode); } } } public static void b() throws Exception{ String className = "classhandle.AsmClass"; ClassReader classReader = new ClassReader(className); ClassWriter classWriter = new ClassWriter(0); classReader.accept(classWriter, 0); FieldVisitor fieldVisitor = classWriter.visitField(Opcodes.ACC_PRIVATE, "name", "Ljava/lang/String;", null, null); fieldVisitor.visitAnnotation("Llombok/Getter;", false); byte[] byteCode = classWriter.toByteArray(); File file = new File("D:\util\mypro\src\main\java\classhandle\" +className.substring(className.lastIndexOf(".")+1)+ ".class"); if ((!file.exists() || file.delete()) && file.createNewFile()) { try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(byteCode); } } } public static void c() throws Exception{ // 创建的类的类名 String implClassName = baseByteCodeHandler.class.getName() + "Impl"; ClassWriter cw = new ClassWriter(0); // 设置class文件结构的版本号、类名、类签名、父类、实现的接口 cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, implClassName.replace(".", "/"), null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(baseByteCodeHandler.class)}); // 创建asyHello方法 MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "order", "()V", null, null); // 插入输出"hello word!"的字节码指令 mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(System.class), "out", Type.getDescriptor(System.out.getClass())); mv.visitLdcInsn("hello word!"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(System.out.getClass()), "println", "(Ljava/lang/String;)V", false); // void方法也需要有return指令 mv.visitInsn(Opcodes.RETURN); // 设置局部变量表和操作数栈的大小 mv.visitMaxs(2,1); // 获取生成的类的字节数组 byte[] byteCode = cw.toByteArray(); } public static void d() throws Exception{ // 创建的类的类名 String subClassName = AsmTest.class.getName() +"Sub"; ClassWriter cw = new ClassWriter(0); // 设置class文件结构的版本号、类名、类签名、父类、实现的接口 cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, subClassName.replace(".", "/"), null, Type.getInternalName(AsmTest.class), null); // 创建方法 MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "d", "()V", null, null); // 调用父类的方法 mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(AsmTest.class), "d", "()V", false); // 插入输出"SubClass sayHello"的字节码指令 mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(System.class), "out", Type.getDescriptor(System.out.getClass())); mv.visitLdcInsn("SubClass sayHello"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(System.out.getClass()), "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); // 设置局部变量表和操作数栈的大小 mv.visitMaxs(2, 1); // 获取生成的类的字节数组 byte[] byteCode = cw.toByteArray(); } }



