2014-01-06 52 views
3

我正在嘗試在Java 6中編寫註釋處理器。我編寫了一個示例實現,它在流程方法中創建了一個新的源文件,並且工作正常。具有Filer.createClassFile()實現的Java 6註釋處理器

@SupportedAnnotationTypes(value = {"*"}) 
@SupportedSourceVersion(SourceVersion.RELEASE_6) 
public class BrownfieldAnnotationProcessor extends AbstractProcessor{ 
    public boolean process(Set<? extends TypeElement> annotations, 
RoundEnvironment roundEnv) { 
     try { 
      JavaFileObject f = processingEnv.getFiler(). 
        createSourceFile("in.test.ExtraClass"); 
      processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, 
        "Creating " + f.toUri()); 
      Writer w = f.openWriter(); 
      try { 
       PrintWriter pw = new PrintWriter(w); 
       pw.println("package in.test;"); 
       pw.println("public class ExtraClass implements TestInterface{"); 
       pw.println(" public void print() {"); 
       pw.println("  System.out.println(\"Hello boss!\");"); 
       pw.println(" }"); 
       pw.println("}"); 
       pw.flush(); 
      } finally { 
       w.close(); 
      } 
     } catch (IOException x) { 
      processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
        x.toString()); 
     } 
    return true; 
} 

}

但在我的情況,我不希望創建另一個Java文件,而是我想直接生成一個類文件。如何創建一個類文件?我應該使用動態編譯器來編譯這個字符串來創建類的源?在這種情況下,我可以直接將類文件存儲在文件系統中。 processingEnv.getFiler()。createClassFile() 方法的用法是什麼?

我試過Google搜索,但無法找到使用此方法的示例。

+1

與具體問題無關,我建議使用像JavaPoet這樣的庫(https://github.com/square/javapoet)來生成代碼,而不是像大括號,保留字,分號等硬編碼。 – jpangamarca

+0

' Filer.createClassFile(..)'在JDK 1.8(build 1.8.0_121-b13)中被破壞。我已經用很多方式測試過它,它從來沒有用過。儘管如此,這樣的功能對於複製以前生成的文件非常有用,而不是使用語句來生成源文件。 – mljrg

回答

2

我看到創建類文件而不是源代碼文件的原因很少。實際上,這與你在任何情況下需要手動創建字節碼的原因都是一樣的。

我認爲你幾乎不需要做任何上述的控制。如果這真的是你想要做的,你當然應該知道很多關於the format of class files和字節碼。你現在基本上會創建一些編譯器。

你可能會爭辯說,通過運送預編譯類,或者直接生成bytcode,你可以跳過構建過程中的一個步驟,用戶程序編譯得更快。這可能是事實,但我相信速度是可以忽略的。只需使用源代碼並將其傳遞給編譯器進行編譯就會更容易。

我應該使用動態編譯器來編譯這個源字符串來創建類嗎?

不,我在這裏看不到優勢。如果使用文件管理器創建源代碼文件,它將自動編譯。如果您的源代碼不是Java,但是您希望爲JVM編譯的某種其他語言,則只需執行此操作。

+0

是的,同意。現在創建src文件而不是類文件。 – user1793318