2012-06-06 51 views
0

我目前正在製作一個工具,根據用戶輸入輸出Java類文件以供使用。我輸出了一組.java文件,其中一些引用了當前上下文中不存在的類和變量。因此,當我編譯時,輸出文件會記錄這些錯誤,並且不會編譯該類。我的問題是:有沒有辦法使用JavaCompiler來編譯類文件?JavaCompiler API強制編譯有錯誤?

這裏的彙編代碼:

public static void compileAll(File file) throws IOException{ 
    String fileToCompile = "C:/test.java"; 
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
    FileOutputStream errorStream = new FileOutputStream("Errors.txt"); 
    int compilationResult = compiler.run(null, null, errorStream, "-verbose", fileToCompile); 
    if(compilationResult == 0){ 
     System.out.println("Compilation is successful"); 
    }else{ 
     System.out.println("Compilation Failed"); 
    } 
} 

回答

0

問:有沒有辦法使用JavaCompiler進行編譯的類文件,是一種方式?

是:根據需要,這樣你就可以編譯:)創建虛擬方法和/或虛擬類

+0

更好的是,將它們定義爲接口,然後添加實現它們的虛擬方法。這種方式取代他們可能會更快。 – SJuan76

+0

所以你說沒有辦法做到這一點?因爲重新制作所有必要的課程將是一件麻煩事。 –

0

你想要什麼是不可能的,因爲Java編譯器需要知道的類型以及名稱字節碼生成時的變量和方法。由於Java字節碼是鍵入的,並且JVM不知道某些Java源級轉換(例如,拆箱轉換純粹是Java編譯器慣例),所以編譯器無法脫離發送字節碼的「加載域f」或「調用方法foo「;編譯器必須說「類型double的加載字段f」或類型int(double, Object)的「調用方法f」。

考慮閱讀對象的未知字段並將其分配給一個double局部變量:

double d = o.f; 

如果f類型是double,編譯器將簡單地使用一個getfield後跟一個dstore到本地可變槽位d。如果f類型爲int,則編譯器將在getfielddstore之間發出i2d指令,以將int轉換爲double。如果f的類型爲Double,則編譯器將發出對doubleValue()的調用,以在存儲它之前取消裝入的值。如果f的類型爲Object,則該分配在Java中沒有強制轉換是非法的(如果它是合法的,它將是checkcast指令)。如果x的類沒有名爲x的字段,則此作業不可能有翻譯。

調用具有未知簽名的方法時可能會有類似的考慮,這可能需要爲每個參數進行轉換和/或爲可變參數調用創建數組。此外,在JVM級別,允許在返回類型上重載,因此即使只有一個參數類型列表,也必須指定返回類型。

您可以做的最好的事情是提供未知類的虛擬聲明,以便編譯器知道該怎麼做,正如paulsm4的答案所建議的那樣。