1、动态编译
动态编译,简单来说就是在Java程序运行时编译源代码。
从JDK1.6开始,引入了Java代码重写过的编译器接口,使得我们可以在运行时编译Java源代码,然后再通过类加载器将编译好的类加载进JVM,这种在运行时编译代码的操作就叫做动态编译。
静态编译:编译时就把所有用到的Java代码全都编译成字节码,是一次性编译。
动态编译:在Java程序运行时才把需要的Java代码的编译成字节码,是按需编译。
静态编译示例:
静态编译实际上就是在程序运行前将所有代码进行编译,我们在运行程序前用Javac命令或点击IDE的编译按钮进行编译都属于静态编译。
比如,我们编写了一个xxx.java
文件,里面是一个功能类,如果我们的程序想要使用这个类,就必须在程序启动前,先调用Javac编译器来生成字节码文件。
如果使用动态编译,则可以在程序运行过程中再对xxx.java
文件进行编译,之后再通过类加载器对编译好的类进行加载,同样能正常使用这个功能类。
动态编译示例:
JDK提供了对应的JavaComplier接口来实现动态编译(rt.jar中的javax.tools包提供的编译器接口,使用的是JDK自带的Javac编译器)。
一个用来进行动态编译的类:
public class TestHello {
public void sayHello(){
System.out.println("hello word");
}
}
编写一个程序来对它进行动态编译:
public class TestDynamicCompilation {
public static void main(String[] args) {
//获取Javac编译器对象
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//获取文件管理器:负责管理类文件的输入输出
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);
//获取要被编译的Java源文件
File file = new File("/project/test/TestHello.java");
//通过源文件获取到要编译的Java类源码迭代器,包括所有内部类,其中每个类都是一个JavaFileObject
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file)