总结:我们大多数时候都是静态编译,写好java 开发工具或者构建 就给编译了,有没有动态生成类,然后执行呢,答案是有的,如动态代理的具体实现。
介绍:
反射:就是通过在运行时获得类型信息然后做相应的操作。
动态编译:动态编译是从Java 6开始支持的,主要是通过一个JavaCompiler接口来完成的。通过这种方式我们可以直接编译一个已经存在的java文件,也可以在内存中动态生成Java代码,动态编译执行。
调用JavaScript引擎:Java 6加入了对Script(JSR223)的支持。这是一个脚本框架,提供了让脚本语言来访问Java内部的方法。你可以在运行的时候找到脚本引擎,然后调用这个引擎去执行脚本。这个脚本API允许你为脚本语言提供Java支持。
动态生成字节码:这种技术通过操作Java字节码的方式在JVM中生成新类或者对已经加载的类动态添加元素。
动态编程解决什么问题
在静态语言中引入动态特性,主要是为了解决一些使用场景的问题。
完全使用静态编程也办的到,只是付出的代价比较高,没有动态编程来的优雅。例如依赖注入框架Spring使用了反射,而Dagger2 却使用了代码生成的方式(APT)。
如
1、在那些依赖关系需要动态确认的场景:
2、需要在运行时动态插入代码的场景,比如动态代理的实现。
3、通过配置文件来实现相关功能的场景
Javassist
操作java字节码的工具BECL/ASM/CGLIB/Javassit
其中有两个比较流行,一个是ASM,一个是Javassit。
ASM 直接操作字节码指令,执行效率高,要是使用者掌握Java类字节码文件格式及指令,对使用者的要求比较高。
Javassit 提供了更高级的API,执行效率相对较差,但无需掌握字节码指令的知识,对使用者要求较低。
Javassit 是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
Javassist中最为重要的是ClassPool,CtClass ,CtMethod 以及 CtField这几个类。
ClassPool:一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。默认的ClassPool使用与底层JVM相同的类路径,因此在某些情况下,可能需要向ClassPool添加类路径或类字节。
CtClass:表示一个类,这些CtClass对象可以从ClassPool获得。
CtMethods:表示类中的方法。
CtFields :表示类中的字段。
这里以jJdkCompiler 为例 参考 dubbo 地址如下:
https://github.com/apache/dubbo/blob/master/dubbo-common/src/main/java/org/apache/dubbo/common/compiler/support/JdkCompiler.java
我的例子如下:
是不是觉得很6,双击666 吧