針對於java sdk1.6的版本對於java動態編譯類的實現:
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class CompileString {
public static void main(String[] args) throws Exception {
//通過系統工具提供者獲得動態編譯器
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//獲得一個檔案管理工具,它的功能主要是提供所有檔案操作的規則,
//如原始碼路徑、編譯的classpath,class檔案目標目錄等,其相關屬性都提供預設值
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
StringObject so = new StringObject("demo.CalculatorTest", "package demo;" +
" class CalculatorTest {" +
" public int multiply(int multiplicand, int multiplier) {" +
" System.out.println(multiplicand);" +
" System.out.println(multiplier);" +
" return multiplicand * multiplier;" +
" }" +
"}");
JavaFileObject file = so;
// 指定 javac 的命令列參數
// 注意:最好將編譯後的.class檔案放到當前JVM執行個體的類路徑上,否則載入不鳥
// Iterable options = Arrays.asList("-d", "E:\\workspace\\hellosbt\\target\\scala-2.9.1\\classes");
Iterable options = Arrays.asList("-d", "E:\\workplace\\javacompiletest\\bin");
// 指定有哪些源檔案需要被編譯
Iterable<? extends JavaFileObject> files = Arrays.asList(file);
//返回編譯對象
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, files);
//執行此編譯任務
Boolean result = task.call();
if (result) {
System.out.println("編譯成功");
//返回類的名字的對應的引用
Class<?> clazz = Class.forName("CalculatorTest");
//Class 對象所表示的類的一個新執行個體
Object instance = clazz.newInstance();
//返回一個 Method
對象,它反映此 Class
對象所表示的類或介面的指定公用成員方法。
Method m = clazz.getMethod("multiply", new Class[]{int.class, int.class});
//對應傳入相應的參數
Object[] o = new Object[]{1, 2};
m.invoke(instance, o);
}
}
}
class StringObject extends SimpleJavaFileObject {
private String contents = null;
public StringObject(String className, String contents) throws Exception {
//Kind.SOURCE表示用 Java 程式設計語言編寫的源檔案
super(new URI(className), Kind.SOURCE);
this.contents = contents;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return contents;
}
}