一、動態編譯
簡單的說就是在運行一個java程序的過程中,可以通過一些API來編譯其他的Java文件。
下面主要說動態編譯的實現:
1、獲取java編譯編譯器
2、運行編譯器(須指定編譯文件)
獲取編譯器通過JavaCompiler ToolProvider.getSystemJavaCompiler();//返回該平台提供的JAVA語言編譯器
運行調用int run(InputStream in,OutputStream out,OutputStream err,String... arguments);
其中in,代表為java編譯器提供信息,out為獲取編譯器輸出信息,err獲取編譯器錯誤信息。
如果設置為null則使用System.in(鍵盤輸入),System.out(控制台輸出),Sytem.err(控制台輸出錯誤信息)。
arguments為字符串類型可變參數,代表被編譯文件地址,可編譯多個文件。方法運行成功返回0。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class TestDynamicCompile { public static void main(String[] args) throws IOException { //獲取編譯器 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //編譯時空指針異常 //文件位置 F:/TestJava/HelloWorld.java //運行編譯器,編譯指定文件 int compilerFlag = compiler.run(null,null,null,"F:/TestJava/HelloWorld.java"); //成功返回0. System.out.println(compilerFlag==0?"true":"false"); } }
運行結果: true
注:這里運行時在
int compilerFlag = compiler.run(null,null,null,"F:/TestJava/HelloWorld.java");
可能會報一個NullPointerException異常,問題原先jre下lib目錄中沒有tools.jar文件,該方法是此文件提供的。
解決方法:點擊IDE菜單欄Window->Preferences->java->installed JREs右側會顯示jre路徑,找到這個路徑中lib在里面添加tools.jar文件。
tools.jar文件在下載的java文件夾中的lib目錄下可以找到(網上有的說是java文件下jdk下的lib)。(實在找不到就搜索,還是找不到網上下)
動態編譯前:
動態編譯后:
二、動態運行
動態運行,即在運行一個java程序的過程中通過調用API,運行另外一個java程序。
要實現這個功能先得了解兩個類:
Runtime:每個java程序都有一個類運行時的實例,允許應用與當前運行環境進行交互。
說的簡單一點,就是在當前平台(windows)上運行的java程序,可以通過這個類來讓當前平台(window)幫我們完成一些操作。
這個類無法通過new來創建對象,只能通過Runtime.getTime()初始化對象。
其中有一個方法,exec(String commad),在單獨的進程中執行指定的命令。
exec這個有些類似:(Windos+R)
帶會可以將exec里面運行java程序的語句改成"notepad.exe",會發現和在上述對話框中輸入后運行的結果是相同的。
都是打開了記事本。在打開(0)中輸如java -cp F:/TestJava HelloWorld ,和在程序中調用exec(java -cp F:/TestJava HelloWorld),
是一樣的結果,但這個對話框中會打印出hello world,但這個對話框一閃而過。
如果了解DOS命令的話:(Windows + R) 然后輸入cmd回車。彈出DOs窗口
運行結果都是一樣的,都是本地運行環境執行指定命令。
exec是本地運行環境執行指定字符串中的命令,結合這兩個理解。
exec執行完后會返回一個Process對象。
Process:可用於控制進程並獲取有關進程的信息。類Process提供了用於執行來自進程的輸入、
執行對進程的輸出、等待進程完成、檢查進程的退出狀態以及銷毀(終止)進程的方法。
流程:1.當前java程序通過getTime()獲取可以和當前平台交互的實例。
2.使用這個實例中的exec方法執行相關操作。(此處的命令是當前運行平台(windows)去執行的)
3.通過exec方法返回Process對象,獲取這個進程的輸入流。
4.通過這個進程的輸入流讀取運行結果,打印到控制台輸出。
這里使用之前動態編譯好的類,程序的運行結果只是輸出Hello World.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class TestDynamicCompile { public static void main(String[] args) throws IOException { Runtime run = Runtime.getRuntime();//獲取與當前平台進行交互的實例 Process process = run.exec("java -cp F:/TestJava HelloWorld");//當前平台執行對應命令 BufferedReader br =new BufferedReader(new InputStreamReader(process.getInputStream()));//獲取執行進程的輸入流 String runInfo = null; while(null != (runInfo = br.readLine())){//讀取執行結果並輸出 System.out.println(runInfo); } } }
運行結果:
Hello World!