栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java ASM

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java ASM

ASM是操作类字节码的工具包,提供ClassVisitor、FieldVisitor、MethodVisito等访问方法

  
      org.ow2.asm
      asm
      6.2
  
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,"","()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();

    }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/331991.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号