java - 在注释处理器中获取没有任何注释的字段类型

标签 java java-11 annotation-processing

我已经为此奋斗了一段时间,依靠各种神秘的转换和 toString 的操作来使其工作,但必须有一种正确的方法来做到这一点。

我有一个如下所示的注释处理器:

@SupportedAnnotationTypes("processor.EchoFields")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class TestProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        roundEnvironment.getElementsAnnotatedWith(EchoFields.class)
                .stream()
                .filter(e -> e.getKind() == ElementKind.CLASS)
                .map(TypeElement.class::cast)
                .forEach(this::echoFields);
        return false;
    }

    private void echoFields(TypeElement element) {
        log("Fields of class %s", element);
        element.getEnclosedElements().stream()
                .filter(e -> e.getKind() == ElementKind.FIELD)
                .map(VariableElement.class::cast)
                .forEach(this::echoField);
    }

    private void echoField(VariableElement element) {
        log("\tField %s of type %s", element.getSimpleName().toString(), element.asType().toString());
        for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
            log("\t\t%s", annotationMirror);
        }
    }

    private void log(String format, Object... parameters) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format(format, parameters));
    }

}

在我的测试类上运行时,如下所示:

@EchoFields
public class Pojo {

    @TypeAnnotation
    @FieldAnnotation
    private List<String> aListOfStrings;
}

(@TypeAnnotation@FieldAnnotation 分别具有目标 TYPE(_USE)FIELD) p>

我得到以下输出:

Note: Fields of class consumer.Pojo
Note:   Field aListOfStrings of type @processor.TypeAnnotation java.util.List<java.lang.String>
Note:           @processor.FieldAnnotation

而我想要的是这样的:

Note: Fields of class consumer.Pojo
Note:   Field aListOfStrings of type java.util.List<java.lang.String>
Note:           @processor.TypeAnnotation
Note:           @processor.FieldAnnotation

重要的部分是 java.util.List<java.lang.String> 没有 @processor.TypeAnnotation - 列表@processor.TypeAnnotation带有注释只是一个额外的好处,而不是我需要的

但我似乎找不到任何方法可以做到这一点。每次我发现删除注释的内容时,我也会丢失类型参数( java.lang.String )。我已经在实现注释处理 API 的类中进行了探索,并且肯定有一些方法可以完成我想要的操作 - 但我找不到任何通过公共(public) API 调用它们的方法,并且我不想依赖于实现详细信息(特别是当我在 JDK 8 上尝试时得到了截然不同的实现)。

有一个可运行的 Gradle 项目,位于 https://github.com/Raniz85/processor-test ,只需克隆并运行 ./gradlew build

最佳答案

由于 TypeAnnotation 被标记为 TYPE+TYPE_USE(请注意,TYPE 与此问题无关)而不是 FIELD,因此它根本不是字段上的注释,但实际上是关于字段的声明类型。您也可以将 TYPE_USE 注释放在其他事物上,例如局部变量 - 但您无法从普通注释处理器中读取它们。来自 How to access TypeUse annotation via AnnotationProcessor :

The TYPE_USE annotations are a bit tricky, because the compiler treats them differently, than the "old usage" annotations.

So as you correctly observed, they are not passed to annotation processor, and your process() method will never receive them.

在不具体知道您要解决什么问题的情况下,很难说您是否真的想要 TYPE_USE 首先,或者您只是在尝试注释可能具有的不同可能目标。也许您只想在这里使用 FIELD,因为您正在编写一个注释处理器(它遍历您的 API,而不是源代码本身,因此您将错过本地变量上的任何 TYPE_USE 等)。

--

此外,使用 TypeMirror.toString() 或 Element.toString() 时要非常小心,在某些环境中这些不会输出您期望的内容。要么使用 Name 类型,要么使用 javapoet 的 TypeName 层次结构之类的东西。

关于java - 在注释处理器中获取没有任何注释的字段类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59825943/

相关文章:

java - 用户自定义文件读取函数导致NullPointerException Java

java - 未定义类型按钮的错误 setonclickListener

Java Web 从 Java 应用程序启动 Eclipse

java - OpenJDK 11 问题 - 客户端在最后一次 UNWRAP 之前完成握手

java - JSR269注解处理 getElementsAnnotatedWith() 每次循环返回所有带注解的元素并且无法区分它属于哪种类型

java - HTML 没有将参数传递给 java 类

java - Amazon Corretto JVM 11 无法识别 JVM 11 标志 PrintHeapAtGC

java - 创建具有特定范围的 java.net.Authenticator

java - 如何通过注解处理工具获取extends接口(interface)?

Java:类型别名支持注释处理工具(APT)吗?