博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java知识点总结(动态字节码操作-Javassist介绍)
阅读量:5796 次
发布时间:2019-06-18

本文共 2459 字,大约阅读时间需要 8 分钟。

Java知识点总结(动态字节码操作-Javassist介绍)

@(Java知识点总结)[Java, 动态字节码操作]

运行时操作字节码可以让我们实现如下功能:

  • 动态生成新的类
  • 动态改变某个类的结构(添加/删除/修改 新的属性/方法)

java常见的字节码操作类库

BCEL
  • Byte Code Engineering Library (BCEL) ,这是 Apache Software Foundation 的 Jakarta 项目的一部分。 BCEL 是 Java classworking 广泛 使用的一种 框架 , 它 可以让您深入 JVM 汇编语言进行类操作的细节。 BCEL 与 Javassist 有不同的处理字节码方法, BCEL 在实际的 JVM 指令层次上进行操作 (BCEL 拥有丰富的 JVM 指令级支持 ) 而 Javassist 所 强调 的是源代码 级别的 工作 。
ASM
  • 是一个轻量级 java 字节码操作框架,直接涉及到 JVM 底层的操作和 指令
CGLIB(Code Generation Library)

是一个强大的,高性能,高质量的 Code

Javassist

是 一个开源的分析、编辑和创建 Java 字节码 的类库 。性能较 ASM 差,跟 cglib 差不多,但是使用简单。很多开源框架都在使用它 。

主页:http://www.csg.ci.i.u-tokyo.ac.jp/~ chiba/javassist

Javassist

使用Javassist需要使用javassist.jar

优势:
  • 比反射开销小,性能高。
  • JAVAsist性能高于反射,低于ASM
局限性:
  • JDK新语法不支持(包括泛型、枚举),不支持注解修改,但可以通过底层的javasist类来解决,具体参考:javassist.bytecode.annotaion
  • 不支持数组的初始化,如 String[]{"1","2"},除非只有数组的容量为1
  • 不支持内部类和匿名类
  • 不支持 continue 和 break 表达式。
  • 对于继承关系,有些不支持 。例如:- class A{} - class B extends A{} - class C enxends B {}
应用场景:
  • AOP:

    • 给一个类增加新的方法
    • 给一段语句前面和后面(before/after/around)动态的加代码
  • Reflection:起到类似反射的效果

javassist 的最外层的 API 和 JAVA 的反射包中的 API 颇为类似 。

它主要由 CtClass , CtMethod, ,以及 CtField 几个类组成。用以执行和 JDK 反射 API 中 java.lang.Class , java.lang.reflect.Method , java.lang.reflect.Method .Field 相同的 操作 。

方法操作
  • 修改已有方法的方法体体(插入代码到已有方法体)
  • 新增方法 删除方法
  • 占位符参数介绍:

clipboard.png

示例:

import javassist.ClassPool;import javassist.CtClass;import javassist.CtConstructor;import javassist.CtField;import javassist.CtMethod;/** * 创建一个新的类 * @author Administrator * */public class Test10 {  public static void main(String[] args) throws Exception {    ClassPool pool = ClassPool.getDefault(); // 类池    CtClass class1 = pool.makeClass("com.gs.Emp");        //创建属性    CtField f1 = CtField.make("private int num;", class1);    CtField f2 = CtField.make("private String name;", class1);    class1.addField(f1);    class1.addField(f2);        //创建方法    CtMethod setName = CtMethod.make("public void setName(String name){this.name = name;}", class1);    CtMethod getName = CtMethod.make("public String getName(){return name;}", class1);    class1.addMethod(setName);    class1.addMethod(getName);        //添加构造器。  如果是带参构造器,需要传递参数类型,基本数据类型用CtClass获取,引用类型,需要用pool获取    CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")}, class1);    constructor.setBody("{this.num = num;this.name = name;}"); //构造器的方法体        class1.writeFile("E:/myjava"); //将上面写好的类,写入到这个工作空间中        System.out.println("生成类成功!");  }}

执行结果:

生成类成功!

clipboard.png

使用反编译工具xjad打开:

clipboard.png

转载地址:http://cabfx.baihongyu.com/

你可能感兴趣的文章
3个概念,入门 Vue 组件开发
查看>>
专访OneAPM创始人何晓阳:APM将是开发者必备服务
查看>>
Beaker:一个基于Electron的点对点Web浏览器
查看>>
没有JS的前端:体积更小、速度更快!
查看>>
数据指标/表现度量系统(Performance Measurement System)综述
查看>>
GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
查看>>
Angular2, NativeScript 和 React Native比较[翻译]
查看>>
论模式在领域驱动设计中的重要性
查看>>
一地鸡毛 OR 绝地反击,2019年区块链发展指南
查看>>
京东AI研究院何晓冬:将先进的技术和模型落地到产业
查看>>
国内首例:飞步无人卡车携手中国邮政、德邦投入日常运营
查看>>
微软将停止对 IE 8、9和10的支持
查看>>
微服务架构会和分布式单体架构高度重合吗
查看>>
如何测试ASP.NET Core Web API
查看>>
《The Age of Surge》作者访谈
查看>>
Python全栈之路系列之字典数据类型
查看>>
2018年测试状况调查
查看>>
jQuery 3.0 Alpha版本发布,开发人员需要在升级前充分测试
查看>>
基于容器服务的持续集成与云端交付(四)- 多种发布方式
查看>>
QCon讲师对对碰——洪小军采访梁宇鹏:就是爱Golang
查看>>