zoukankan      html  css  js  c++  java
  • 字节码类库之Javassist

    Javassist优势

    – 比反射开销小,性能高。
    –javassist性能高于反射,低于ASM
    运行时操作字节码可以让我们实现如下功能:
    – 动态生成 新的类
    – 动态改变某个类的结构 ( 添加 / 删除 / 修改 新的属性 / 方法 )
    javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为 类似 。
    它 主要 由 CtClass , CtMethod, ,以及 CtField 几个类组成。用以执行和 JDK 反射 API 中 java.lang.Class, java.lang.reflect.Method, java.lang.reflect.Method .Field 相同的 操作 。
    方法操作
    – 修改已有方法的方法体(插入代码到已有方法体)
    – 新增方法 删除方法


    javassist的局限性
    JDK5.0 新语法不支持 ( 包括泛型、枚举 ) ,不支持注解修改,但可以通过底层的 javassist 类来解决,具体参考: javassist.bytecode.annotation
    不支持数组的初始化,如 String[]{"1","2"} ,除非只有数组的容量为 1
    不支持内部类和匿名类
    不支持 continue 和 break表达式。
    对于继承关系,有些不支持。例如
    class A {}  
    class B extends A {} 
    class C extends B {} 

    创建类:

    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtConstructor;
    import javassist.CtField;
    import javassist.CtMethod;
    import javassist.CtNewConstructor;
    
    public class App {
    
        public static void main(String[] args) throws Exception {
            // 利用javassist 创建类
    
            ClassPool poll = ClassPool.getDefault();
            // 创建类名 全路径
            CtClass ctClass = poll.makeClass("com.hella.thread.jvm.javassist.User");
            // 创建属性
            CtField name = CtField.make("private String name;", ctClass);
            CtField age = CtField.make("private String age;", ctClass);
    
            // 属性添加到类中
            ctClass.addField(name);
            ctClass.addField(age);
    
            // 创建get set 方法
            CtMethod getName = CtMethod.make("public void getName(){return name;}", ctClass);
            CtMethod setName = CtMethod.make("public void setName(String name) {this.name = name;}", ctClass);
            CtMethod getAge = CtMethod.make("public String getAge() {return age;}", ctClass);
            CtMethod setAge = CtMethod.make("public void setAge(String age) {this.age = age;}", ctClass);
    
            // 方法添加到类中
            ctClass.addMethod(getName);
            ctClass.addMethod(setName);
            ctClass.addMethod(getAge);
            ctClass.addMethod(setAge);
    
            // 创建构造方法
            CtConstructor constructor = CtNewConstructor
                    .make("public User(String name, String age) { this.name = name;this.age = age;}", ctClass);
    
            ctClass.addConstructor(constructor);
    
            // 生成的位置
            ctClass.writeFile("C:/Users/caich5/Desktop/test");
        }
    
    }

    修改类的信息

    public class User {
    
        private String name;
    
        private String age;
    
        // 通过字节码技术,在这个类添加以下的方法
    
        // public int calcute(int a,int b){
        // return a + b;
        // }
    
    }

    修改并且执行:

    import java.lang.reflect.Method;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtMethod;
    
    public class Test {
        public static void main(String[] args) throws Exception {
    
            ClassPool poll = ClassPool.getDefault();
            // 获取到class
            CtClass ctClass = poll.get("com.hella.thread.jvm.javassist.User");
            CtMethod ctMethod = CtMethod.make("public int calcute(int a,int b){ return a + b ;}", ctClass);
            ctClass.addMethod(ctMethod);
            ctClass.writeFile("C:/Users/caich5/Desktop/test");
    
            // 使用反射执行
            Class<?> clazz = ctClass.toClass();
            Object newInstance = clazz.newInstance();
            Method method = clazz.getDeclaredMethod("calcute", int.class, int.class);
            Object res = method.invoke(newInstance, 1, 2);
            System.out.println(res);
    
            // 需要添加的方法 也可以这样写
            // CtMethod m = new CtMethod(CtClass.intType, "add", new CtClass[] {
            // CtClass.intType, CtClass.intType },
            // userClass);
            // // 方法权限
            // m.setModifiers(Modifier.PUBLIC);
            // // 方法体内容
            // m.setBody("{System.out.println("Test003"); return $1+$2;}");
        }
    
    }
  • 相关阅读:
    c++标准库容器【转】
    C++命名空间的解释 【转】
    [转载]定义、公理、定理、推论、命题和引理的区别
    待读论文
    矩阵分解 Matrix Factorization (RegularSVD) 实验总结
    Predicting the Next Location: A Recurrent Model with Spatial and Temporal Contexts AAAI2016
    Discovering Urban Functional Zones Using Latent Activity Trajectories TKDE 2015
    numpy
    python 编程 规范
    深度学习
  • 原文地址:https://www.cnblogs.com/pickKnow/p/11128864.html
Copyright © 2011-2022 走看看