我正在尝试使用注释处理器和注释镜像读取注释中的枚举值,但我得到了空值。我认为这与将枚举包装为变量元素的 AnnotationValue 有关。VariableElement#getConstantValue() 的文档说“如果这是初始化为编译时常量的最终字段,则返回此变量的值。” 好的,但 final 不是注释成员的有效修饰符。另外值得注意的是,我可以毫无困难地阅读其他注释值,只是枚举。
我做了一些调查,看起来 AnnotationValue 在运行时被实例化为 Symbol.VarSymbol,但 Symbol.VarSymbol#getConstantValue() 看起来应该只返回对象。
最后,如果我对 AnnotationValue 执行 toString(),我会得到正确的值。
注释:
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;
    }
}