一
使用Java API來編譯Java源程序有很多方法
我們可以通過ToolProvider類的靜態方法getSystemJavaCompiler來得到一個JavaCompiler接口的實例
JavaCompiler compiler = ToolProvider
JavaCompiler中最核心的方法是run
int run(InputStream in
如果前
int results = tool
下面是使用JavaCompiler的完整代碼
import java
import javax
public class test_compilerapi
{
public static void main(String args[]) throws IOException
{
JavaCompiler compiler = ToolProvider
int results = compiler
System
// 在程序中運行test
Runtime run = Runtime
Process p = run
BufferedInputStream in = new BufferedInputStream(p
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String s;
while ((s = br
System
}
}
public class test
{
public static void main(String[] args) throws Exception
{
System
}
}
編譯成功的輸出結果
編譯成功
JavaCompiler測試成功
編譯失敗的輸出結果
test
符號
位置
System
^
編譯失敗
二
在第一部分我們討論調用java編譯器的最容易的方法
使用StandardJavaFileManager需要兩步
在使用這種方法調用Java編譯時最復雜的方法就是getTask
DiagnosticListener<? super JavaFileObject> diagnosticListener
Iterable<String> options
Iterable<String> classes
Iterable<? extends JavaFileObject> compilationUnits)
這些參數大多數都可為null
·out:
·fileManager:
·diagnosticListener: 編譯器的默認行為
·options: 編譯器的選項
·classes
最後一個參數compilationUnits不能為null
在使用完getTask後
Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
Iterable<? extends File> files)
Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(
Iterable<String> names)
String[] filenames = …;
Iterable<? extends JavaFileObject> compilationUnits =
fileManager
JavaCompiler
diagnostics
最後需要關閉fileManager
下面是一個完整的演示程序
import java
import java
import javax
public class test_compilerapi
{
private static void compilejava() throws Exception
{
JavaCompiler compiler = ToolProvider
// 建立DiagnosticCollector對象
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler
// 建立用於保存被編譯文件名的對象
// 每個文件被保存在一個從JavaFileObject繼承的類中
Iterable<? extends JavaFileObject> compilationUnits =
fileManager
JavaCompiler
diagnostics
// 編譯源程序
boolean success = task
fileManager
System
}
public static void main(String args[]) throws Exception
{
compilejava();
}
}
如果想得到具體的編譯錯誤
for (Diagnostic diagnostic : diagnostics
System
diagnostic
diagnostic
diagnostic
diagnostic
被編譯的test
public class test
{
public static void main(String[] args) throws Exception
{
aa; //錯誤語句
System
}
}
在這段代碼中多寫了個aa
Code: compiler
Kind: ERROR
Position:
Start Position:
End Position:
Source: test
Message: test
Success: false
通過JavaCompiler進行編譯都是在當前目錄下生成
Iterable<String> options = Arrays
JavaCompiler
diagnostics
在上面的例子中options處的參數為null
有時我們編譯一個Java源程序文件
Iterable<String> options = Arrays
上面的代碼指定的被編譯Java文件所依賴的源文件所在的目錄
三
JavaCompiler不僅可以編譯硬盤上的Java文件
import java
import java
import javax
import javax
import java
import
public class test_compilerapi
{
private static void compilerJava() throws Exception
{
JavaCompiler compiler = ToolProvider
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
// 定義一個StringWriter類
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
// 開始寫Java程序
out
out
out
out
out
out
//為這段代碼取個名子
JavaFileObject file = new JavaSourceFromString(
Iterable<? extends JavaFileObject> compilationUnits = Arrays
JavaCompiler
diagnostics
boolean success = task
System
// 如果成功
if (success)
{
System
Class
{ String[]
{ null });
System
}
}
public static void main(String args[]) throws Exception
{
compilerJava();
}
}
// 用於傳遞源程序的JavaSourceFromString類
class JavaSourceFromString extends SimpleJavaFileObject
{
final String code;
JavaSourceFromString(String name
{
super(URI
de = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
{
return code;
}
}
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19545.html