脚本宝典收集整理的这篇文章主要介绍了Java知识点总结(动态字节码操作-Javassist介绍),脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
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 相同的 操作 。
方法操作
- 修改已有方法的方法体体(插入代码到已有方法体)
- 新增方法 删除方法
- 占位符参数介绍:
示例:
@H_76_126@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("生成类成功!"); } }
执行结果:
生成类成功!
使用反编译工具xjad打开:
以上是脚本宝典为你收集整理的Java知识点总结(动态字节码操作-Javassist介绍)全部内容,希望文章能够帮你解决Java知识点总结(动态字节码操作-Javassist介绍)所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。