我正在尝试通过 Java 8 中的编译时注释处理为我的源代码生成配置文件。
据我了解,对于 getSupportedAnnotationTypes
类中列出的每个注释,处理器都会被调用一次。
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> set = new LinkedHashSet<>();
set.add(MCPlugin.class.getCanonicalName());
set.add(MCAPIVersion.class.getCanonicalName());
set.add(MCAuthor.class.getCanonicalName());
set.add(MCAPIVersion.class.getCanonicalName());
set.add(MCDepend.class.getCanonicalName());
set.add(MCLoad.class.getCanonicalName());
set.add(MCLoadBefore.class.getCanonicalName());
set.add(MCSoftDepend.class.getCanonicalName());
set.add(MCCommand.class.getCanonicalName());
return set;
}
实际上,我不想用一个注释处理器处理所有这些注释(这是正确的方法吗?),因为它会导致 MCCommand
注释出现问题。
所以我的计划是创建另一个注释处理器,它只处理 MCCommand
注释。
我的问题是,两个处理器的输出应该进入同一个输出文件。 (这可能吗?)
我已经尝试像这样重新打开资源文件(这也是我首先打开它的方式):
FileObject file = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "config.yml");
这只会产生错误或覆盖现有文件。
TlDr:如何让我的注释处理器编辑另一个注释处理器生成的文件?
最佳答案
好吧,经过几个小时的检查 Filer
和 FileObject
的源代码,我找到了一个解决方案/解决方法。
为了能够访问 JavacFiler
,您需要将 com.sun.tools 作为依赖项。
将Filer
向下转换为JavacFiler
以访问更多方法。
文件管理器有一个 createResource(...)
和一个 getResource(...)
方法,它们的作用似乎相同,但不同之处在于 createResource( ...)
打开一个 FileObject
仅供写入,并打开 getResource(...)
仅供读取。
因此,为了能够从另一个注释处理器编辑文件,您必须执行以下操作:
- 以只读方式打开文件
- 读取文件内容
- 关闭文件
- 以只写方式重新打开文件
- 将旧内容写入其中
- 添加更多数据
FileObject jfo = filer.getResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
String msg = TUtils.JFOToString(jfo); // Reads FileObject as String
jfo.delete();
jfo = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
TUtils.writeJFO(jfo, msg + "Hallo ich bin Processor 2"); // Writes String to FileObject
filer.close();
这感觉像是黑客,但我似乎可以工作。
关于Java注释处理编辑由注释处理器与其他注释处理器创建的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59201101/