JDK6.0的新特性:使用Compiler API

xuniji123發表於2007-01-02
現在我們可以用JDK6 的Compiler API(JSR 199)去動態編譯Java原始檔,Compiler API結合反射功能就可以實現動態的產生Java程式碼並編譯執行這些程式碼,有點動態語言的特徵。這個特性對於某些需要用到動態編譯的應用程式相當有用, 比如JSP Web Server,當我們手動修改JSP後,是不希望需要重啟Web Server才可以看到效果的,這時候我們就可以用Compiler API來實現動態編譯JSP檔案,當然,現在的JSP Web Server也是支援JSP熱部署的,現在的JSP Web Server透過在執行期間透過Runtime.exec或ProcessBuilder來呼叫javac來編譯程式碼,這種方式需要我們產生另一個程式去做編譯工作,不夠優雅而且容易使程式碼依賴與特定的作業系統;Compiler API透過一套易用的標準的API提供了更加豐富的方式去做動態編譯,而且是跨平臺的。 下面程式碼演示了Compiler API的使用:

public class CompilerAPITester {
 private static String JAVA_SOURCE_FILE = "DynamicObject.java";
 private static String JAVA_CLASS_FILE = "DynamicObject.class";
 private static String JAVA_CLASS_NAME = "DynamicObject";
 public static void main(String[] args) {
  JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
  generateJavaClass();
  try {
   //將產生的類檔案複製到程式的ClassPath下面,下面這一行程式碼是特定於Windows+IntelliJ IDEA 6.0專案,不具有移植性
   Runtime.getRuntime().exec("cmd /c copy "+JAVA_CLASS_FILE+" classesproductionJDK6Features");
   Iterable extends JavaFileObject> sourcefiles = fileManager.getJavaFileObjects(JAVA_SOURCE_FILE);
   compiler.getTask(null, fileManager, null, null, null, sourcefiles).call();
   fileManager.close();
   Class.forName(JAVA_CLASS_NAME).newInstance();//建立動態編譯得到的DynamicObject類的例項
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

 public static void generateJavaClass(){
  try {
   FileWriter fw = new FileWriter(JAVA_SOURCE_FILE);
   BufferedWriter bw = new BufferedWriter(fw);
   bw.write("public class "+JAVA_CLASS_NAME+"{");
   bw.newLine();
   bw.write("public "+JAVA_CLASS_NAME+"(){System.out.println("In the constructor of DynamicObject");}}");
   bw.flush();
   bw.close();
  } catch (IOException ex) {
   ex.printStackTrace();
  }
 }
}

  程式執行後,會產生DynamicObject.java和DynamicObject.class兩個檔案,並在控制檯輸出:

  In the constructor of DynamicObject[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8271432/viewspace-888021/,如需轉載,請註明出處,否則將追究法律責任。

相關文章