Javassist简介
要想将编译时不存在的类在运行时动态创建并加载,通常有两种策略:
动态编译
动态生成二进制字节码(.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简介 javassist可以对一个已经编译好了的.class文件的字节码进行改动,比如说我可以为一个类添加一个方法,添加一个属性,也可以修改一个方法等,还可以对一个方法,异常进行拦截 ...
- com.rr.domain.Department_$$_javassist_5 cannot be cast to javassist.util.proxy.Proxy
com.rr.domain.Department_$$_javassist_5 cannot be cast to javassist.util.proxy.Proxy 两个原因: 1.懒加载 在we ...
- Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
- Spring教程--AOP简介
AOP的简介 1 什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存 ...
- JVM插桩之四:Java动态代理机制的对比(JDK和CGLIB,Javassist,ASM)
一.class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件, ...
- Javaassist简介
1.简介 Javassist(JAVA programming ASSISTant)是在Java中编辑字节码的类库:它使Java程序能够在运行时定义一个新类,并在JVM加载是修改类文件. 我们常用到的 ...
- Java成神之路——ASM,Javassist,cglib区别。
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
- dubbo和zookeper使用_Dubbox与Zookeeper简介及入门小案例
Dubbox 一:简介 Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继 ...
- ASM、Javassist、JDK、CGLIB
ASM/Javassist/JDK/CGLIB 简介 ASM是一款基于java字节码层面的代码分析和修改工具. ASM的目标是生成,转换和分析已编译的java class文件,可使用ASM工具读/写/ ...
- mybatis 简介、中文文档、中英对照文档 下载
mybatis 文档 下载链接(含jar包.源码.pom) 组件名称 中文-文档-下载链接 中英对照-文档-下载链接 mybatis-3.2.8.jar mybatis-3.2.8-API文档-中文版 ...
最新文章
- 看阿里高手使用Jmeter做功能测试的优缺点
- JVM锁和分布式锁是什么关系
- Python json使用实例:字符串与对象互转代码示例
- centos上那装qq2012
- java中泛型上限,下限应用
- 为什么我选择工作很难做选择_为什么公开工作(即使很难)
- 2017.10.6 Java命名规范及使用情况
- 关于ddx/ddy重建法线在edge边沿上的artifacts问题
- opencv fast角检测
- iOS求职之OC面试题
- LINUX使用C执行系统命令ping,读取执行结果的崩溃日志
- 汪文君高并发编程总结-第一阶段
- 继承者来了!CentOS 创始人开辟新项目 Rocky Linux
- 【Spring】注解驱动开发
- 数组旋转(上下对称,主对角线对称)
- Lora、zigbee比较
- 细讲如何对NFA确定化和最小化
- python的CUDA加速编程科普
- clearCallingIdentity与restoreCallingIdentity-千里马framework系统源码实战详解
- 限定学校|在站博士后省公派新加坡国立大学从事博后研究
热门文章
- Reading Note(3)——基于FPGA的动态可重构特性探索新型加速器架构
- linux双击脚本不弹出选择框,在安装msicuu2.exe的时候不能安装弹出对话框windows脚本宿主是怎么回事?...
- 哪个邮箱域名好?域名是永久的吗?
- java web 车辆管理系统_javaweb车辆信息管理系统
- NB-IoT独立式烟感在出租屋的防火安全应用
- 令牌环(Token-Ring)
- C++ 小游戏程序 (共七款)
- win7查询计算机硬盘sn,电脑win7系统查询硬盘序列号的方法
- Fedora Linux 14百度云下载,Fedora Linux 14下载
- java vm参数设置_Java VM 启动参数详解