要想将编译时不存在的类在运行时动态创建并加载,通常有两种策略

  1. 动态编译

  2. 动态生成二进制字节码(.class)

对于第二种策略,实际上已经有诸多比较成熟的开源项目提供支持,如CGLib、ASM、Javassist等。这些开源项目通常都具备两方面的功能

  1. 动态创建新类或新接口的二进制字节码

  2. 动态扩展现有类或接口的二进制字节码

其中,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));  }  }  

最后需要特别注意的是:

  1. Javassist不支持要创建或注入的类中存在泛型参数

  2. Javassist对@类型的注解(Annotation)只支持查询,不支持添加或修改

Javassist简介相关推荐

  1. javassist 初步学习

    javassist简介 javassist可以对一个已经编译好了的.class文件的字节码进行改动,比如说我可以为一个类添加一个方法,添加一个属性,也可以修改一个方法等,还可以对一个方法,异常进行拦截 ...

  2. 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 ...

  3. Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...

  4. Spring教程--AOP简介

    AOP的简介 1 什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存 ...

  5. JVM插桩之四:Java动态代理机制的对比(JDK和CGLIB,Javassist,ASM)

    一.class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件, ...

  6. Javaassist简介

    1.简介 Javassist(JAVA programming ASSISTant)是在Java中编辑字节码的类库:它使Java程序能够在运行时定义一个新类,并在JVM加载是修改类文件. 我们常用到的 ...

  7. Java成神之路——ASM,Javassist,cglib区别。

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...

  8. dubbo和zookeper使用_Dubbox与Zookeeper简介及入门小案例

    Dubbox 一:简介 Dubbox 是一个分布式服务框架,其前身是阿里巴巴开源项目Dubbo ,被国内电商及互联网项目中使用,后期阿里巴巴停止了该项目的维护,当当网便在Dubbo基础上进行优化,并继 ...

  9. ASM、Javassist、JDK、CGLIB

    ASM/Javassist/JDK/CGLIB 简介 ASM是一款基于java字节码层面的代码分析和修改工具. ASM的目标是生成,转换和分析已编译的java class文件,可使用ASM工具读/写/ ...

  10. mybatis 简介、中文文档、中英对照文档 下载

    mybatis 文档 下载链接(含jar包.源码.pom) 组件名称 中文-文档-下载链接 中英对照-文档-下载链接 mybatis-3.2.8.jar mybatis-3.2.8-API文档-中文版 ...

最新文章

  1. 看阿里高手使用Jmeter做功能测试的优缺点
  2. JVM锁和分布式锁是什么关系
  3. Python json使用实例:字符串与对象互转代码示例
  4. centos上那装qq2012
  5. java中泛型上限,下限应用
  6. 为什么我选择工作很难做选择_为什么公开工作(即使很难)
  7. 2017.10.6 Java命名规范及使用情况
  8. 关于ddx/ddy重建法线在edge边沿上的artifacts问题
  9. opencv fast角检测
  10. iOS求职之OC面试题
  11. LINUX使用C执行系统命令ping,读取执行结果的崩溃日志
  12. 汪文君高并发编程总结-第一阶段
  13. 继承者来了!CentOS 创始人开辟新项目 Rocky Linux
  14. 【Spring】注解驱动开发
  15. 数组旋转(上下对称,主对角线对称)
  16. Lora、zigbee比较
  17. 细讲如何对NFA确定化和最小化
  18. python的CUDA加速编程科普
  19. clearCallingIdentity与restoreCallingIdentity-千里马framework系统源码实战详解
  20. 限定学校|在站博士后省公派新加坡国立大学从事博后研究

热门文章

  1. Reading Note(3)——基于FPGA的动态可重构特性探索新型加速器架构
  2. linux双击脚本不弹出选择框,在安装msicuu2.exe的时候不能安装弹出对话框windows脚本宿主是怎么回事?...
  3. 哪个邮箱域名好?域名是永久的吗?
  4. java web 车辆管理系统_javaweb车辆信息管理系统
  5. NB-IoT独立式烟感在出租屋的防火安全应用
  6. 令牌环(Token-Ring)
  7. C++ 小游戏程序 (共七款)
  8. win7查询计算机硬盘sn,电脑win7系统查询硬盘序列号的方法
  9. Fedora Linux 14百度云下载,Fedora Linux 14下载
  10. java vm参数设置_Java VM 启动参数详解