Как получить Перечисление от AnnotationValue в Процессоре Аннотации

Я пытаюсь считать значение перечисления в аннотации с помощью процессора аннотации и зеркала аннотации, но я возвращаю пустой указатель. Я думаю, что это имеет отношение к AnnotationValue, переносящему Перечисление как VariableElement. В документе для VariableElement#getConstantValue () говорится, "Возвращает значение этой переменной, если это - заключительное поле, инициализированное к постоянному времени компиляции". Хорошо, но финал не является допустимым модификатором для участника аннотации. Также знаменитый, я не испытываю никаких затруднений при чтении других значений аннотации, просто Перечисления.

Я сделал, некоторые выслеживающие это кажутся, что AnnotationValue инстанцируют как Символ. VarSymbol во времени выполнения, но Символ. VarSymbol#getConstantValue () похож на него, должен просто возвратить объект.

Наконец, если я делаю toString () на AnnotationValue, я получаю собственное значение.

Аннотация:

package annotation;
public @interface AnAnnotation
{
    String value();
    Behavior defaultBehavior() default Behavior.NEW;

    public static enum Behavior
    {
        NEW, NULL;
    }
}

Часть моего Процессора и вложенный во множестве циклов для достигания надлежащего AnnotaionMirror:

Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValues = elemUtils.getElementValuesWithDefaults(annotationMirror);
for (ExecutableElement method : annotationValues.keySet())
{
    ...
    else if ("defaultBehavior".equals(method.getSimpleName().toString()))
    {

        defaultBehavior = (Behavior)( (VariableElement)annotationValues.get(method).getValue()).getConstantValue();

        // This prints "NEW" or "NULL" correctly
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,annotationValues.get(method).toString());
        // This prints null incorrectly (expect "NEW" or "NULL")
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, defaultBehavior + "");

    }
    ...
}

Править: больше полной версии Процессора.

package annotation.processor;

import java.util.*;

import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.*;
import javax.tools.*;

import annotation.AnAnnotation;
import annotation.AnAnnotation.Behavior;

@SupportedAnnotationTypes("annotation.AnAnnotation")
public class AnAnnotationProcessor extends AbstractProcessor
{
    Types typeUtils;
    Elements elemUtils;

    @Override
    public void init(ProcessingEnvironment processingEnv)
    {
        super.init(processingEnv);
        typeUtils = processingEnv.getTypeUtils();
        elemUtils = processingEnv.getElementUtils();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv)
    {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
            "Entering AnnotationNullableClassProcessor");

        /****** Iterate over all annotaions being processed (only AnAnnotation) ******/
        for (TypeElement annotation : annotations)
        {
            /****** Iterate over all elements that are annotated with the annotation ******/
            for (Element element : roundEnv.getElementsAnnotatedWith(annotation))
            {
                /****** Iterate over all the declared annotations of the element ******/
                for (AnnotationMirror annotationMirror :  element.getAnnotationMirrors())
                {
                    final String annotationTypeName = annotationMirror.getAnnotationType().toString();

                    // Process annotations of type AnAnnotation
                    if (annotationTypeName.equals(AnAnnotation.class.getName()))
                    {
                        Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValues = elemUtils.getElementValuesWithDefaults(annotationMirror);

                        /****** Iterate over the annotation's values. ******/
                        for (ExecutableElement method : accessorValues.keySet())
                        {
                            if ("defaultBehavior".equals(method.getSimpleName().toString()))
                            {
                                Behavior defaultBehavior = (Behavior)( (VariableElement)annotationValues.get(method).getValue()).getConstantValue();

                                // This prints "NEW" or "NULL" correctly
                                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,annotationValues.get(method).toString());
                                // This prints null incorrectly (expect "NEW" or "NULL")
                                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, defaultBehavior + "");
                            }
                        }
                    }
                }
            }
        }

        return true;
    }
}
5
задан J Hall 22 June 2010 в 01:11
поделиться

1 ответ

Из документации для getConstantValue:

«В частности, константы перечисления не считаются константами времени компиляции. Чтобы иметь постоянное значение, тип поля должен быть либо примитивным типом, либо String».

http://java.sun.com/javase/6/docs/api/javax/lang/model/element/VariableElement.html#getConstantValue()

Чтобы получить значение константы перечисления, используйте API getAnnotation или используйте AnnotationValueVisitor.

3
ответ дан 15 December 2019 в 00:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: