zoukankan      html  css  js  c++  java
  • 字节码操作-Javaassist

    下面就是一个具体的demo来介绍利用Javaassist库来创建类,不过要先在工程里面导入Javaassist的架包,

    package JavaAasist;
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtConstructor;
    import javassist.CtField;
    import javassist.CtMethod;
    import javassist.CtNewMethod;
    import javassist.Modifier;
    
    /**
    * 测试javassist的API
    * @author 尚学堂高淇 www.sxt.cn
    *
    */
    public class DEmo02 {
    /**
    * 处理类的基本用法
    * @throws Exception 
    */
    public static void test01() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.bjsxt.test.Emp");
    
    byte[] bytes = cc.toBytecode();
    System.out.println(Arrays.toString(bytes));
    
    System.out.println(cc.getName()); //获取类名
    System.out.println(cc.getSimpleName()); //获取简要类名
    System.out.println(cc.getSuperclass()); //获得父类
    System.out.println(cc.getInterfaces()); //获得接口
    
    }
    
    /**
    * 测试产生新的方法
    * @throws Exception 
    */
    public static void test02() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.bjsxt.test.Emp");
    
    //    CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
    
    CtMethod m = new CtMethod(CtClass.intType,"add",
    new CtClass[]{CtClass.intType,CtClass.intType},cc);
    m.setModifiers(Modifier.PUBLIC);
    m.setBody("{System.out.println("www.sxt.cn");return $1+$2;}");
    
    cc.addMethod(m);
    
    //通过反射调用新生成的方法
    Class clazz = cc.toClass();
    Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
    Method method = clazz.getDeclaredMethod("add", int.class,int.class);
    Object result = method.invoke(obj, 200,300);
    System.out.println(result);
    }
    
    /**
    * 修改已有的方法的信息,修改方法体的内容
    * @throws Exception
    */
    public static void test03() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.bjsxt.test.Emp");
    
    CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
    cm.insertBefore("System.out.println($1);System.out.println("start!!!");");
    cm.insertAt(9, "int b=3;System.out.println("b="+b);");
    cm.insertAfter("System.out.println("end!!!");");
    
    //通过反射调用新生成的方法
    Class clazz = cc.toClass();
    Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
    Method method = clazz.getDeclaredMethod("sayHello", int.class);
    method.invoke(obj, 300);
    }
    
    /**
    * 属性的操作
    * @throws Exception
    */
    public static void test04() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.bjsxt.test.Emp");
    
    //    CtField f1 = CtField.make("private int empno;", cc);
    CtField f1 = new CtField(CtClass.intType,"salary",cc);
    f1.setModifiers(Modifier.PRIVATE);
    cc.addField(f1);
    
    //    cc.getDeclaredField("ename"); //获取指定的属性
    
    //增加相应的set和get方法
    cc.addMethod(CtNewMethod.getter("getSalary", f1));;
    cc.addMethod(CtNewMethod.getter("setSalary", f1));;
    
    }
    
    /**
    * 构造方法的操作
    * @throws Exception
    */
    public static void test05() throws Exception {
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("com.bjsxt.test.Emp");
    
    CtConstructor[] cs = cc.getConstructors();
    for (CtConstructor c : cs) {
    System.out.println(c.getLongName());
    }
    }
    
    
    public static void test06() throws Exception{
    CtClass cc = ClassPool.getDefault().get("com.bjsxt.test.Emp"); 
    Object[] all = cc.getAnnotations();
    Author a = (Author)all[0]; 
    String name = a.name();
    int year = a.year();
    System.out.println("name: " + name + ", year: " + year);
    
    }
    
    
    public static void main(String[] args) throws Exception {
    test06();
    }
    }

    运行改代码则在对应路径生成一个java文件,不过该文件需要反编译才可以查看,具体的工具是xjad

    下面是JavaAssist处理类的demo

    package JavaAssist;
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    import javassist.ClassPool;
    import javassist.CtClass;
    import javassist.CtConstructor;
    import javassist.CtField;
    import javassist.CtMethod;
    import javassist.CtNewMethod;
    import javassist.Modifier;
    
    /**
    * 测试javassist的API
    * @author 19579
    *
    */
    public class DEmo02 {
    /**
    * 处理类的基本用法
    * @throws Exception 
    */
    public static void test01() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("JavaAssist.Emp");
    
    byte[] bytes = cc.toBytecode();
    System.out.println(Arrays.toString(bytes));
    
    System.out.println(cc.getName()); //获取类名
    System.out.println(cc.getSimpleName()); //获取简要类名
    System.out.println(cc.getSuperclass()); //获得父类
    System.out.println(cc.getInterfaces()); //获得接口
    
    }
    
    /**
    * 测试产生新的方法
    * @throws Exception 
    */
    public static void test02() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("JavaAssist.Emp");
    
    //    CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
    
    CtMethod m = new CtMethod(CtClass.intType,"add",
    new CtClass[]{CtClass.intType,CtClass.intType},cc);
    m.setModifiers(Modifier.PUBLIC);
    m.setBody("{System.out.println("www.sxt.cn");return $1+$2;}");//$1和$2分别指两个形参
    
    cc.addMethod(m);
    
    //通过反射调用新生成的方法
    Class clazz = cc.toClass();
    Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
    Method method = clazz.getDeclaredMethod("add", int.class,int.class);
    Object result = method.invoke(obj, 200,300);
    System.out.println(result);
    }
    
    /**
    * 修改已有的方法的信息,修改方法体的内容
    * @throws Exception
    */
    public static void test03() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("JavaAssist.Emp");
    
    CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
    cm.insertBefore("System.out.println($1);System.out.println("start!!!");");//在方法体前加入
    cm.insertAt(9, "int b=3;System.out.println("b="+b);");//具体的第9行加入
    cm.insertAfter("System.out.println("end!!!");");//在方法后面加入
    
    //通过反射调用新生成的方法
    Class clazz = cc.toClass();
    Object obj = clazz.newInstance(); //通过调用Emp无参构造器,创建新的Emp对象
    Method method = clazz.getDeclaredMethod("sayHello", int.class);
    method.invoke(obj, 300);
    }
    
    /**
    * 属性的操作
    * @throws Exception
    */
    public static void test04() throws Exception{
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("JavaAssist.Emp");
    
    //    CtField f1 = CtField.make("private int empno;", cc);
    CtField f1 = new CtField(CtClass.intType,"salary",cc);
    f1.setModifiers(Modifier.PRIVATE);
    cc.addField(f1);
    
    //    cc.getDeclaredField("ename"); //获取指定的属性
    
    //增加相应的set和get方法
    cc.addMethod(CtNewMethod.getter("getSalary", f1));;
    cc.addMethod(CtNewMethod.getter("setSalary", f1));;
    
    }
    
    /**
    * 构造方法的操作
    * @throws Exception
    */
    public static void test05() throws Exception {
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("JavaAssist.Emp");
    
    CtConstructor[] cs = cc.getConstructors();
    for (CtConstructor c : cs) {
    System.out.println(c.getLongName());
    }
    }
    
    
    public static void test06() throws Exception{
    CtClass cc = ClassPool.getDefault().get("JavaAssist.Emp"); 
    Object[] all = cc.getAnnotations();
    Author a = (Author)all[0]; 
    String name = a.name();
    int year = a.year();
    System.out.println("name: " + name + ", year: " + year);
    
    }
    
    
    public static void main(String[] args) throws Exception {
    test06();
    }
    }

    对应的emp类如下

    package com.bjsxt.test;
    
    
    @Author(name="gaoqi", year=2014) 
    public class Emp {
    
    private int empno;
    private String ename;
    
    public void sayHello(int a){
    System.out.println("sayHello,"+a);
    }
    
    public int getEmpno() {
    return empno;
    }
    public void setEmpno(int empno) {
    this.empno = empno;
    }
    public String getEname() {
    return ename;
    }
    public void setEname(String ename) {
    this.ename = ename;
    }
    
    public Emp(int empno, String ename) {
    super();
    this.empno = empno;
    this.ename = ename;
    }
    
    public Emp() {
    }
    }
    
    Author类如下
    
    package com.bjsxt.test;
    public @interface Author { 
    String name(); 
    int year();
    }

    当然javaAssist也有自己的局限性

  • 相关阅读:
    .NET开源系统
    DEDEcms二次开发数据表参数
    dede系统的pagebreak文章页面分页数量控制方法
    窗口最小化到托盘
    SEO项目各个阶段的工作分配
    scrollTop
    去除行内块间的间距
    jquery mobile
    nodejs学习
    cancelAnimationFrame无效
  • 原文地址:https://www.cnblogs.com/henuliulei/p/9573984.html
Copyright © 2011-2022 走看看