javassist

文章介绍了如何利用Javassist库动态创建并修改Java类的字节码,包括添加字段、构造器、方法,以及设置访问权限和初始化值。通过ClassPool和CtClass对象,可以直观地操作class文件,并将其写入磁盘。
摘要由CSDN通过智能技术生成

今日收获:

Javassist 学习

先写一下ssist的优点,因为class字节码文件是不可视化的,但是运用了javassist我们可以直接生成class文件并且可以很直观的看到并且,最重要的是我们可以直接修改class文件。

 ClassPool pool = ClassPool.getDefault();  //是存储CtClass对象的容器,
        //创建一个空类com.y4er.learn.Person
        CtClass ctClass = pool.makeClass("src.main.java.com.cxk.ssit.Person");
        //给ctclass类添加一个string类型的字段name
        CtField name = new CtField(pool.get("java.lang.String"), "name", ctClass);

        //设置private权限
        name.setModifiers(Modifier.PRIVATE);

        //初始化name字段为zhangsan
        ctClass.addField(name,CtField.Initializer.constant("zhangsan"));

        //生成get、set方法
        ctClass.addMethod(CtNewMethod.getter("getName",name));
        ctClass.addMethod(CtNewMethod.setter("setName",name));

        //添加无参构造函数
        CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
        ctConstructor.setBody("{name=\"xiaocai\";}");
        ctClass.addConstructor(ctConstructor);

        //添加有参构造
        CtConstructor ctConstructor1 = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, ctClass);
        ctConstructor1.setBody("{$0.name=$1;}");
        //$0代表this  $1代表第一个传入的参数,默认自动含有$0
        ctClass.addConstructor(ctConstructor1);

        //创建一个public方法printName()无参无返回值
        CtMethod printName = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, ctClass);
        printName.setModifiers(Modifier.PUBLIC);
        printName.setBody("{System.out.println($0.name);}");
        ctClass.addMethod(printName);

        ctClass.writeFile();// 写入.class文件
        ctClass.detach();//从ClassPool中删除类

第一步:ClassPool.getDefault   声明一个存储CtClass对象的容器

第二步:pool.makeClass("Person") 创建一个名为Person的class文件,参数是Person路径

  • new CtField(pool.get("java.lang.String"), "name", ctClass) CtField添加变量
  • sist中,无论用什么类都需要pool.get导入, 别的和反射区别不大
  1. name.setModifiers(Modifier.PRIVATE);    设置name变量的类型为private,也可以是public.
  2. ctClass.addField(name,CtField.Initializer.constant("zhangsan"));  初始化name的值
  3. ctClass.addMethod(CtNewMethod.getter("getName",name));  为name变量添加get方法
  4.  new CtConstructor(new CtClass[]{}, ctClass); 无参构造,如果是有参new CtClass[]{pool.get("java.lang.String")}
  5. setBody("{name=\"xiaocai\";}");  body顾名思义身体,也就是往方法中添加东西,默认有this的标志,比如 this.name="xiaocai"
  6. ctClass.addConstructor(ctConstructor1);
      身体添加完后需要,添加到我们声明的类中
  7. new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, ctClass);                        添加新的方法,void无参数,        方法名字        
  8. ctClass.writeFile();// 写入.class文件  最重要的一步
  9. 反射的关键是,ctfClass.toClass().newInstance()                                                                      toClass() 函数直接将 CtClass 转换成 Class对象,不然没write写入是不能调用的,
            Object o = ctClass.toClass().newInstance();
            Method setName = o.getClass().getMethod("setName", String.class);
            Object y4er = setName.invoke(o, "Y4er");
    
            Method printName1 = o.getClass().getMethod("printName");
            printName1.invoke(o);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值