Я пытаюсь считать значение перечисления в аннотации с помощью процессора аннотации и зеркала аннотации, но я возвращаю пустой указатель. Я думаю, что это имеет отношение к 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;
}
}
Из документации для getConstantValue:
«В частности, константы перечисления не считаются константами времени компиляции. Чтобы иметь постоянное значение, тип поля должен быть либо примитивным типом, либо String».
Чтобы получить значение константы перечисления, используйте API getAnnotation или используйте AnnotationValueVisitor.