Javassit介绍

Javassist

动态生成字节码技术。操作java字节码的工具有两个比较流行,一个是ASM,一个是Javassit 。

  • ASM :直接操作字节码指令,执行效率高,要是使用者掌握Java类字节码文件格式及指令,对使用者的要求比较高。
  • Javassist: 提供了更高级的API,执行效率相对较差,但无需掌握字节码指令的知识,对使用者要求较低。

Javassist是一个开源的分析、编辑和创建Java字节码的类库。Javassist中最为重要的是ClassPoolCtClassCtMethod 以及 CtField这几个类。

  • ClassPool:一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。默认的ClassPool使用与底层JVM相同的类路径,因此在某些情况下,可能需要向ClassPool添加类路径或类字节。
  • CtClass:表示一个类,这些CtClass对象可以从ClassPool获得。
  • CtMethods:表示类中的方法。
  • CtFields :表示类中的字段。

下面,编写一个简单的实例,演示一下Javassist的使用:

  1. 先编写一个model类,取名为Student,代码如下:

 

public class Student {
}

这里需要说明一下的是,这是一个空的class,没有任何的属性和方法。下面我们就使用Javassist,进行动态编程。

  1. Javassist的使用代码,代码如下:

 

public class TestJavassitCompiler {

    public static void main(String[] args) throws Exception{
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.makeClass("com.hui.wang.dubbo.learn.provider.javassist.model.Student");

        //添加属性:private String name
        CtField nameField = new CtField(pool.getCtClass("java.lang.String"), "name", ctClass);
        nameField.setModifiers(Modifier.PRIVATE);
        ctClass.addField(nameField);

        //添加属性:private int age
        CtField ageField = new CtField(pool.getCtClass("int"), "age", ctClass);
        ageField.setModifiers(Modifier.PRIVATE);
        ctClass.addField(ageField);

        //getter和setter
        ctClass.addMethod(CtNewMethod.getter("getName", nameField));
        ctClass.addMethod(CtNewMethod.setter("setName", nameField));
        ctClass.addMethod(CtNewMethod.getter("getAge", ageField));
        ctClass.addMethod(CtNewMethod.setter("setAge", ageField));

        //创建构造器
        CtConstructor ctConstructor = new CtConstructor(new CtClass[] {}, ctClass);
        String body = new StringBuilder("{\nthis.age = 1;\nthis.name = \"hui.wang\";\n}").toString();
        ctConstructor.setBody(body);
        ctClass.addConstructor(ctConstructor);

        //普通方法
        CtMethod ctMethod = new CtMethod(CtClass.voidType, "commonMethod", new CtClass[] {}, ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC);
        ctMethod.setBody(new StringBuilder("{\n System.out.println(\"this is a common method\"); \n" +
                "\n System.out.println(this.getAge()); \n}").toString());
        ctClass.addMethod(ctMethod);

        Class<?> clazz = ctClass.toClass();
        Object obj = clazz.newInstance();
        //方法调用
        obj.getClass().getMethod("commonMethod", new Class[] {}).invoke(obj, new Object[] {});
    }
}

打印结果为:

 

this is a common method
1

 

参考

https://www.jianshu.com/p/d06a85d4b22a

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值