java - 获取注释处理器中生成的注释的所有值

标签 java annotations annotation-processing

我有一个 VariableElement 字段,它使用生成的注释进行注释(这就是我不能使用 field.getAnnotation(annotationClass) 的原因)。我需要获取传递给此注释的所有参数。

请注意,“生成的注解”的意思是注解类本身(不是注解类)本身是由注解处理器生成的。被注解的字段/类在手写源码中。

看起来并没有那么难,到目前为止我已经想到了这个:

for (AnnotationMirror annotation : field.getAnnotationMirrors()) {
    Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValueMap = annotation.getElementValues();

    messager.printMessage(Diagnostic.Kind.WARNING, annotation.toString() + ":" + annotationValueMap.toString());
}

我以为这样就可以了,但该字段的输出如下:

@MyAnnotation:{}

因此,处理器确实识别出该字段已注释,但我无法访问传递的参数。即使该字段被定义地注释并且确实通过注释传递参数(它必须这样做,因为注释定义了必需的参数并且没有默认值):

@MyAnnotation(max = 387, min = 66876, ...)
private Integer myField;

这是生成的注释代码:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface MyAnnotation {
  int max();

  boolean allowAuto();

  int min();
}

我已经多次干净地编译项目,处理器从未看到这些值。我在这里忽略了什么?处理器显然可以看到注释本身,但传递给它的参数是隐藏的。

最佳答案

回想一下,注解处理器作为编译器的一部分在称为“轮”的步骤中运行。这个过程迭代运行,直到没有新代码要编译,然后处理器得到最后一次运行的机会(对于这个答案不是必需的,但对更多上下文有帮助)。每一轮只有新创建的类型被直接提供给处理器进行检查。

这里似乎正在发生的事情是, 一轮中,您发出了一个新的注释类型,这应该允许处理器观察提交编译的某些代码的某些特征。但是,在下一轮开始之前,在给定轮次期间创建的任何类型都不会被编译。

对于这个问题,我们在这里遇到了冲突 - 编译了一些 Java 源代码,它们使用了 尚不存在的注释。处理器首先创建注释,然后尝试从那些部分编译的源代码中读取新创建的注释。不幸的是,在注释被编译之前,我们无法真正读取注释。相反,我们需要等到下一轮(一旦注释本身已编译),然后返回已完成编译的类并检查它。

这可以自己实现,没有太多麻烦,但最简单的方法通常是依赖 google/auto 项目(特别是 auto-common 库,参见 https://github.com/google/auto/tree/master/common ),并扩展它们的 BasicAnnotationProcessor类。它支持的一个很好的特性是自动检查类型并检查是否存在任何编译问题 - 如果存在,它们将被推迟到下一轮,这样您就可以在没有任何类型解析问题的情况下处理它们。

关于java - 获取注释处理器中生成的注释的所有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55172210/

相关文章:

Java 注释处理器 - 带注释的 Kotlin 类单元测试

kotlin - 将 Mapstruct 与 Kotlin 一起用于生成源时出现 NonExistentClass 错误

java - Spring Boot 的默认 session 存储是什么?

java - 正则表达式在java中验证用户名

java - 在这种情况下,字符串构造函数 - String(String original) 中的 'size > originalValue.length' 会是 0x104567910 吗?

ios - Core Plot 1.0 我的触摸注释不起作用

go - 如何仅调用具有注释或标签的特定函数

java - NetBeans 声明式操作注册与节点弹出菜单

Java注解处理intellij需要编译两次

java - 纹理环绕模式重复不起作用