Java 关于客户注释处理器,为什么getElementsAnnotatedWith()返回的集合大小为0

Java 关于客户注释处理器,为什么getElementsAnnotatedWith()返回的集合大小为0,java,java-8,annotations,Java,Java 8,Annotations,我正在学习Java中的注释。我发现了两个问题,我不知道为什么 以下是我的测试代码: @Documented @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE, ElementType.FIELD}) public @interface MyTag {} temp2.txt pw2 can work here 0 temp3.txt only pw3 can work id 注释处理可以在多轮中完成,这意味着一个处理

我正在学习Java中的注释。我发现了两个问题,我不知道为什么

以下是我的测试代码:

@Documented
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface MyTag {}


temp2.txt

pw2 can work here
0
temp3.txt

only pw3 can work
id

注释处理可以在多轮中完成,这意味着一个处理器可能被多次调用,使用不同的输入

在您的例子中,处理器似乎被调用了两次。不幸的是,由于
PrintWriter
覆盖了旧文件,
temp1.txt
中的输出仅来自第二轮。第一轮的输出看起来是正确的:

pw1 can work here
2
pw1 can't work here
pw1 can't work here
第二轮不处理注释中的任何元素,因此集合为空。因为这次循环没有执行,
temp2.txt
temp3.txt
不会被覆盖,并且仍然显示第一轮的输出。为了更好地了解正在发生的情况,您可以向处理器添加计数器,并向文件名添加计数器,例如:

private int round = 0;

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    round++;

    //...
    pw1 = new PrintWriter(new File("temp1-" + round + ".txt"));
    //...
}

包含元素时返回大小为0的集合听起来很奇怪,不应该发生。我的猜测是,您要么正在运行旧版本的代码,要么正在看到前一次运行的输出。如果一切都是正确的,那么我会用一个debugger@kapex谢谢你回答我的问题,我的jdk版本是1.8.0_181。我将MyClass.java、MyProcessor.class、MyTag.class放在一个文件夹中。并使用cmd编译MyClass.java。所以我得到了MyClass.class,temp1.txt,temp2.txt,temp.txt。在temp1.txt中有两个词:“pw1可以在这里工作”和“0”。在temp2.txt中有两个词:“pw2可以在这里工作”和“0”。在temp3.txt中有一个词:“只有pw3可以工作”和“id”。所以我不知道为什么。我是一个初学者,所以我不知道如何调试好。这是我第一次使用这个网站。我不确定我是否已通过@通知你。如果你已经收到通知,请原谅我@卡佩克斯没问题,欢迎来到Stackoverflow:)我收到了通知,但只看到了第一句话,没有看到评论的更新。所以很高兴你再发一次。能否尝试将所有“临时”文件名更改为其他名称并再次运行?如果您这样做,并且创建的新文件的内容与以前相同,那么您至少可以确保所有文件都正确编译。:),好的,我已将所有文件名更改为“temp1.txt”,如“temp1.txt”。并且只将three.java文件放在一个文件夹中。我首先使用
cmd
编译
MyTag.java
MyProcessor.java
。然后我使用cmd来编译
MyClass.java
“-processor-MyProcessor”
。像“temp_1.txt”这样的文件创建得很好,其中的内容仍然像“temp1.txt”(正如我前面提到的)。cmd中没有警告(至少我看不到)。所以我认为编译过程可能运行得很好@谢谢你!你说的真有帮助!
only pw3 can work
id
pw1 can work here
2
pw1 can't work here
pw1 can't work here
private int round = 0;

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    round++;

    //...
    pw1 = new PrintWriter(new File("temp1-" + round + ".txt"));
    //...
}
processingEnv.getMessager().printMessage(Kind.NOTE, "MyProcessor, processing round: " + round);