zoukankan      html  css  js  c++  java
  • javassist实例

    我们常用到的动态特性主要是反射,在运行时查找对象属性、方法,修改作用域,通过方法名称调用方法等。在线的应用不会频繁使用反射,因为反射的性能开销较大。其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassist。

    Javassist其实就是一个二方包,提供了运行时操作Java字节码的方法。Java代码编译完会生成.class文件,就是一堆字节码。JVM(准确说是JIT)会解释执行这些字节码(转换为机器码并执行),由于字节码的解释执行是在运行时进行的,那我们能否手工编写字节码,再由JVM执行呢?答案是肯定的,而Javassist就提供了一些方便的方法,让我们通过这些方法生成字节码。

    重要的类:

    ClassPool:javassist的类池,使用ClassPool 类可以跟踪和控制所操作的类,它的工作方式与 JVM 类装载器非常相似,
    CtClass: CtClass提供了检查类数据(如字段和方法)以及在类中添加新字段、方法和构造函数、以及改变类、父类和接口的方法。不过,Javassist 并未提供删除类中字段、方法或者构造函数的任何方法。
    CtField:用来访问域
    CtMethod :用来访问方法
    CtConstructor:用来访问构造器

    实例:

    Example1:

     1 public class Example1 {
     2     public static void main(String[] args) throws Exception {
     3         ClassPool pool = ClassPool.getDefault();
     4         CtClass cc = pool.makeClass("bean.User");
     5 
     6         //创建属性
     7         CtField field01 = CtField.make("private int id;",cc);
     8         CtField field02 = CtField.make("private String name;", cc);
     9         cc.addField(field01);
    10         cc.addField(field02);
    11 
    12         //创建方法
    13         CtMethod method01 = CtMethod.make("public String getName(){return name;}", cc);
    14         CtMethod method02 = CtMethod.make("public void setName(String name){this.name = name;}", cc);
    15         cc.addMethod(method01);
    16         cc.addMethod(method02);
    17 
    18         //添加有参构造器
    19         CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType, pool.get("java.lang.String")}, cc);
    20         constructor.setBody("{this.id=id;this.name=name;}");
    21         cc.addConstructor(constructor);
    22         //无参构造器
    23         CtConstructor cons = new CtConstructor(null, cc);
    24         cons.setBody("{}");
    25         cc.addConstructor(cons);
    26 
    27         cc.writeFile("E:/workspace/TestCompiler/src");
    28     }
    29 }

    Person:

     1 public class Person {
     2 
     3     public Person() {}
     4 
     5     public Person(int id, String name) {
     6         this.id = id;
     7         this.name = name;
     8     }
     9 
    10     private int id;
    11 
    12     private String name;
    13 
    14     public int getId() {
    15         return id;
    16     }
    17 
    18     public void setId(int id) {
    19         this.id = id;
    20     }
    21 
    22     public String getName() {
    23         return name;
    24     }
    25 
    26     public void setName(String name) {
    27         this.name = name;
    28     }
    29 
    30     public String hello(String name) {
    31         return name;
    32     }
    33 
    34 }

    Example2:

     1 public class Example2 {
     2 
     3     //获取类的简单信息
     4     public static void test01() throws Exception{
     5         ClassPool pool = ClassPool.getDefault();
     6         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
     7         //得到字节码
     8         byte[] bytes = cc.toBytecode();
     9         System.out.println(Arrays.toString(bytes));
    10         System.out.println(cc.getName());//获取类名
    11         System.out.println(cc.getSimpleName());//获取简要类名
    12         System.out.println(cc.getSuperclass());//获取父类
    13         System.out.println(cc.getInterfaces());//获取接口
    14         System.out.println(cc.getMethods());//获取
    15     }
    16     //新生成一个方法
    17     public static void test02() throws Exception{
    18         ClassPool pool = ClassPool.getDefault();
    19         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
    20         //第一种
    21         //CtMethod cm = CtMethod.make("public String getName(){return name;}", cc);
    22         //第二种
    23         //参数:返回值类型,方法名,参数,对象
    24         CtMethod cm = new CtMethod(CtClass.intType,"add", new CtClass[]{CtClass.intType, CtClass.intType}, cc);
    25         cm.setModifiers(Modifier.PUBLIC);//访问范围
    26         cm.setBody("{return $1+$2;}");
    27         //cc.removeMethod(m) 删除一个方法
    28         cc.addMethod(cm);
    29         //通过反射调用方法
    30         Class clazz = cc.toClass();
    31         Object obj = clazz.newInstance();//通过调用无参构造器,生成新的对象
    32         Method m = clazz.getDeclaredMethod("add", int.class, int.class);
    33         Object result = m.invoke(obj, 2, 3);
    34         System.out.println(result);
    35     }
    36 
    37     //修改已有的方法
    38     public static void test03() throws Exception{
    39         ClassPool pool  = ClassPool.getDefault();
    40         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
    41 
    42         CtMethod cm = cc.getDeclaredMethod("hello",new CtClass[]{pool.get("java.lang.String")});
    43         cm.insertBefore("System.out.println("调用前");");//调用前
    44         cm.insertAt(31, "System.out.println("31");");//行号
    45         cm.insertAfter("System.out.println("调用后");");//调用后
    46 
    47         //通过反射调用方法
    48         Class clazz = cc.toClass();
    49         Object obj = clazz.newInstance();
    50         Method m = clazz.getDeclaredMethod("hello", String.class);
    51         Object result = m.invoke(obj, "张三");
    52         System.out.println(result);
    53     }
    54 
    55     //修改已有属性
    56     public static void test04() throws Exception{
    57         ClassPool pool  = ClassPool.getDefault();
    58         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
    59 
    60         //属性
    61         CtField cf = new CtField(CtClass.intType,"age",cc);
    62         cf.setModifiers(Modifier.PRIVATE);
    63         cc.addField(cf);
    64         //增加响应的get set方法
    65         cc.addMethod(CtNewMethod.getter("getAge",cf));
    66         cc.addMethod(CtNewMethod.setter("setAge",cf));
    67 
    68         //访问属性
    69         Class clazz = cc.toClass();
    70         Object obj = clazz.newInstance();
    71         Field field = clazz.getDeclaredField("age");
    72         System.out.println(field);
    73         Method m = clazz.getDeclaredMethod("setAge", int.class);
    74         m.invoke(obj, 16);
    75         Method m2 = clazz.getDeclaredMethod("getAge", null);
    76         Object resutl = m2.invoke(obj,null);
    77         System.out.println(resutl);
    78     }
    79 
    80     //操作构造方法
    81     public static void test05() throws Exception{
    82         ClassPool pool = ClassPool.getDefault();
    83         CtClass cc = pool.get("com.code.javassistdemo.example.Person");
    84 
    85         CtConstructor[] cons = cc.getConstructors();
    86         for(CtConstructor con:cons){
    87             System.out.println(con);
    88         }
    89     }
    90     public static void main(String[] args) throws Exception {
    91         test01();
    92 //        test02();
    93 //        test03();
    94 //        test04();
    95 //        test05();
    96     }
    97 }
  • 相关阅读:
    HDU 1003 Max Sum
    HDU 1728 逃离迷宫
    UVA 10057 A midsummer night's dream.
    HDU 1232 畅通工程
    poj3331
    poj3481
    poj1053
    poj3281
    poj3199
    !!! Gridview的多种使用方法总结
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/10766855.html
Copyright © 2011-2022 走看看