java注解处理器:如何从注解中提取类值

vsnjm48y  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(398)

如何提取价值 Class[] value() 在注解中

package com.example;

public @interface ExampleAnnotation {
    Class[] value();
}

如果没有注解,则在注解处理器的运行时开始。

owfi6suc

owfi6suc1#

我使用为自己的注解处理器构建的以下实用程序 typesprocessingEnv.getTypeUtils() ```
public List getClassArrayValueFromAnnotation(Element element, Class<? extends Annotation> annotation, String paramName) {

List<TypeMirror> values = new ArrayList<>();

for (AnnotationMirror am : element.getAnnotationMirrors()) {
    if (types.isSameType(am.getAnnotationType(), elements.getTypeElement(annotation.getCanonicalName()).asType())) {
        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : am.getElementValues().entrySet()) {
            if (paramName.equals(entry.getKey().getSimpleName().toString())) {
                List<AnnotationValue> classesTypes = (List<AnnotationValue>) entry.getValue().getValue();
                Iterator<? extends AnnotationValue> iterator = classesTypes.iterator();

                while (iterator.hasNext()) {
                    AnnotationValue next = iterator.next();
                    values.add((TypeMirror) next.getValue());
                }
            }
        }
    }
}
return values;

}

mlmc2os5

mlmc2os52#

这是我最好的方法。为了更简单,我使用了javastreamapi。
在处理器类中编写:

public static final String TARGET = "com.example.ExampleAnnotation";

    @Override
    public boolean process(Set<? extends TypeElement> types, RoundEnvironment environment) {
        //process once!
        if (!environment.processingOver())
            //For us to not depend on a class in this runtime
            //try to find the TypeElement of it
            types.stream()
                    .filter(type -> type.getQualifiedName().contentEquals(TARGET))
                    .findAny()
                    .ifPresent(type ->
                            //it exists!
                            //let us see elements annotated with it!
                            environment.getElementsAnnotatedWith(type)
                                    .forEach(element ->
                                            //got an element!
                                            //let us iterate over the annotation mirrors it has got
                                            //then search for the annotation with the targeted type
                                            element.getAnnotationMirrors()
                                                    .stream()
                                                    .filter(annotation -> this.processingEnv.getTypeUtils().isSameType(type.asType(), annotation.getAnnotationType()))
                                                    .findAny()
                                                    .ifPresent(annotation -> {
                                                        //bingo!
                                                        //lets get its values
                                                        Map<? extends ExecutableElement, ? extends AnnotationValue> values = annotation.getElementValues();

                                                        //lets find the annotation value `Class[] value()`
                                                        //any inappropriate value will be simply IGNORED (do not die strategy)
                                                        //this block trusts the javax documentation only!
                                                        //see javax.lang.model.element.AnnotationValue
                                                        List<TypeMirror> value = values.entrySet()
                                                                .stream()
                                                                .filter(entry -> entry.getKey().getSimpleName().contentEquals("value"))
                                                                .findAny()
                                                                .map(entry -> entry.getValue().getValue())
                                                                .filter(List.class::isInstance)
                                                                .<List<AnnotationValue>>map(List.class::cast)
                                                                .map(list ->
                                                                        list.stream()
                                                                                .map(AnnotationValue::getValue)
                                                                                .filter(TypeMirror.class::isInstance)
                                                                                .map(TypeMirror.class::cast)
                                                                                .collect(Collectors.toList())
                                                                )
                                                                .orElseGet(Collections::emptyList);

                                                        //Operate below ---------------------------------
                                                        //Operate above --------------------------------
                                                    })
                                    )
                    );

        return false;
    }

相关问题