Javassist简介
来源:互联网 发布:华师大公共数据库 编辑:程序博客网 时间:2024/06/15 01:04
要想将编译时不存在的类在运行时动态创建并加载,通常有两种策略:
动态编译
动态生成二进制字节码(.class)
对于第二种策略,实际上已经有诸多比较成熟的开源项目提供支持,如CGLib、ASM、Javassist等。这些开源项目通常都具备两方面的功能:
动态创建新类或新接口的二进制字节码
动态扩展现有类或接口的二进制字节码
其中,CGLib的底层基于ASM实现,是一个高效高性能的生成库;而ASM是一个轻量级的类库,但需要涉及到JVM的操作和指令;相比而言,Javassist要简单的多,完全是基于Java的API,但其性能相比前二者要差一些。
尽管如此,在性能要求相对低的场合,Javassist仍然十分有用,如JBoss中就调用了Javassist。
Javassist的官方网站如下:
http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
如下的链接是一个很好的Javassist代码示例:
http://yonglin4605.iteye.com/blog/1396494
如下的链接深入研究了Javassist中的一些语法,其中第8小节处对参数形式的总结很有作用:
http://zhxing.iteye.com/blog/1703305
如下的链接是IBM DW关于Javassist一个较为完整的教程:
http://www.ibm.com/developerworks/cn/java/j-dyn0916/
如下的代码是动态创建Java类二进制字节码并通过反射调用的示例,可供参考:
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import javassist.CtField; import javassist.CtNewMethod; import javassist.Modifier; import javassist.NotFoundException; import javassist.CtField.Initializer; public class JavassistGenerator { public static void main(String[] args) throws CannotCompileException, NotFoundException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { // 创建类 ClassPool pool = ClassPool.getDefault(); CtClass cls = pool.makeClass("cn.ibm.com.TestClass"); // 添加私有成员name及其getter、setter方法 CtField param = new CtField(pool.get("java.lang.String"), "name", cls); param.setModifiers(Modifier.PRIVATE); cls.addMethod(CtNewMethod.setter("setName", param)); cls.addMethod(CtNewMethod.getter("getName", param)); cls.addField(param, Initializer.constant("")); // 添加无参的构造体 CtConstructor cons = new CtConstructor(new CtClass[] {}, cls); cons.setBody("{name = \"Brant\";}"); cls.addConstructor(cons); // 添加有参的构造体 cons = new CtConstructor(new CtClass[] {pool.get("java.lang.String")}, cls); cons.setBody("{$0.name = $1;}"); cls.addConstructor(cons); // 打印创建类的类名 System.out.println(cls.toClass()); // 通过反射创建无参的实例,并调用getName方法 Object o = Class.forName("cn.ibm.com.TestClass").newInstance(); Method getter = o.getClass().getMethod("getName"); System.out.println(getter.invoke(o)); // 调用其setName方法 Method setter = o.getClass().getMethod("setName", new Class[] {String.class}); setter.invoke(o, "Adam"); System.out.println(getter.invoke(o)); // 通过反射创建有参的实例,并调用getName方法 o = Class.forName("cn.ibm.com.TestClass").getConstructor(String.class).newInstance("Liu Jian"); getter = o.getClass().getMethod("getName"); System.out.println(getter.invoke(o)); } }
最后需要特别注意的是:
Javassist不支持要创建或注入的类中存在泛型参数
Javassist对@类型的注解(Annotation)只支持查询,不支持添加或修改
- javassist 简介
- Javassist简介
- Javassist学习1:简介
- javassist
- Javassist
- Javassist
- JAVAssist
- Javassist
- javassist
- javassist教程
- javassist示例
- javassist详细资料
- Javassist总结
- Javassist详解
- javassist用法
- Javassist介绍
- javassist用法
- ASM javassist
- 限制时间内只能点击一次并且做提示 thinkphp
- Python 基础
- JS监听手机端浏览器的后退按钮的事件方法
- xpath抓取代理IP并检测IP的有效性
- 什么是Web前端?Web前端学习什么?
- Javassist简介
- PHPEXCEL出现FORMULA ERROR的解决方案
- 实际业务中碰到的几种ajax请求方法总结
- Re:从零开始的实习生活05----vue调试神器vue-devtools安装
- Java中的时间
- jidnserror.wo.com.cn:8080错误解决方法
- Android使用pullablelistview控件性能优化CUP占用过高
- Nginx 安装步骤
- iOS开发:iOS10.2手机系统打开相册遇到的各种显示英文文字的问题