Java 在批注处理器中获取不带任何批注的字段类型

Java 在批注处理器中获取不带任何批注的字段类型,java,java-11,annotation-processing,Java,Java 11,Annotation Processing,我已经为此挣扎了一段时间,依靠各种奥术施放和对toString的操纵来让它工作,但必须有一个正确的方法来做到这一点 我有一个注释处理器,看起来像这样: @SupportedAnnotationTypes("processor.EchoFields") @SupportedSourceVersion(SourceVersion.RELEASE_11) public class TestProcessor extends AbstractProcessor { @Override p

我已经为此挣扎了一段时间,依靠各种奥术施放和对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;
}
@SupportedAnnotationTypes(“processor.EchoFields”)
@SupportedSourceVersion(SourceVersion.RELEASE_11)
公共类TestProcessor扩展了AbstractProcessor{
@凌驾

公共布尔进程(设置为,因为
TypeAnnotation
标记为TYPE+TYPE\u USE(请注意,TYPE与此问题无关)而不是字段,它根本不是字段上的批注,但实际上是字段声明类型上的批注。您也可以在其他对象(如局部变量)上放置类型\使用批注,但您无法从普通批注处理器读取它们。从:

类型使用注释有点棘手,因为编译器对待它们的方式与“旧用法”注释不同

因此,正如您正确观察到的,它们不会传递给注释处理器,并且您的process()方法将永远不会接收它们

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

--


另外,在使用TypeMirror.toString()或Element.toString()时要非常小心,在某些环境中,这些将不会输出您所期望的内容。请使用名称类型或类似javapoet的TypeName层次结构的内容。

如问题中所述,我对使用类型\u use注释并不感兴趣,它只会给我带来一些问题。我该如何为我的类型获取名称?为了澄清,我要encount其他类型在我的实际处理器中使用注释,它们导致了这个问题。
TypeName
来自JavaPoet,修复了这个问题,尽管它让我感到困扰,我需要拉一个库来处理它获取一个
名称
需要一个
元素
,而不是
类型镜像
-任何作为DeclaredType实例的类型镜像都可以然后被强制转换为DeclaredType,然后您可以对其调用
asElement()
。元素然后具有
getSimpleName()
,以及
getEnclosuringElement()
,以获取父类或包(如果有的话)。这些工具是JavaPoet使用的,但您当然可以自己实现。处理泛型有点困难,但仍然不是神奇的-您将使用TypeMirror并编写一个访问者,再次检查对象中的每个类型,就像JavaPoet内部所做的那样。
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