2014-01-06 95 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