1. 程式人生 > >8.3(java學習筆記)動態編譯(DynamicCompiler)與動態執行(DynamicRun)

8.3(java學習筆記)動態編譯(DynamicCompiler)與動態執行(DynamicRun)

一、動態編譯

  簡單的說就是在執行一個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!