Java動態編譯
阿新 • • 發佈:2019-04-26
code rgs pac 工程 tool getname rri n) tac
Java動態編譯
最近熟悉了一下反射,對Java的動態性有了進一步的了解,因此想實現一下用Java直接動態生成.class文件,也就是在編譯完成後,運行時編譯java文件
工程結構
? helloworld tree
.
├── bin
│?? └── helloworld
│?? ├── Car.java
├── src
│?? └── helloworld
│?? ├── TestDynamicCompile.java
測試程序
TestDynamicCompile.java
package helloworld; import java.net.MalformedURLException; import java.util.Scanner; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class TestDynamicCompile { public static void main(String[] args) throws InstantiationException, IllegalAccessException, MalformedURLException { Scanner scanner = new Scanner(System.in); String className = "helloworld.Car";//scanner.next(); // "helloworld.Car" scanner.close(); try { Class.forName(className); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block System.out.println("Class not found"); System.out.println("dynamic compiling..."); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // 等同於javac 命令,生成的class文件默認在.java文件的同一個文件夾下 int flag = compiler.run(null, null, null, "bin/helloworld/Car.java"); System.out.println(flag==0? "編譯成功" : "編譯失敗"); } try { Class<?> c = Class.forName(className); Object obj = c.newInstance(); System.out.println(obj); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
將被動態編譯的程序
Car.java(放在bin/helloworld目錄下)
package helloworld; public class Car { private String name; private int ID; @Override public String toString() { return "name = " + name + " ID = " + ID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getID() { return ID; } public void setID(int ID) { this.ID = ID; } public Car(){ this.name = "Default"; this.ID = 123; } }
編譯TestDynamicCompile.java
? helloworld tree
.
├── bin
│?? └── helloworld
│?? ├── Car.java
│?? └── TestDynamicCompile.class
├── src
│?? └── helloworld
│?? ├── TestDynamicCompile.java
可以看到Car還未被編譯,TestDynamicCompile.class已經靜態編譯完成
運行後
? helloworld tree . ├── bin │?? └── helloworld │?? ├── Car.class │?? ├── Car.java │?? └── TestDynamicCompile.class ├── src │?? └── helloworld │?? ├── TestDynamicCompile.java
可以看到Car.class字節文件在運行時被JavaCompiler編譯出來
運行輸出
Class not found
dynamic compiling...
編譯成功
name = Default ID = 123
小結
Java實現了"自舉",可以自己編譯自己,而不用再起一個javac進程來外部編譯。感覺這種註入代碼的方式有一定的靈活性。
Java動態編譯