简体   繁体   中英

Annotation processor: get all enum values from a TypeMirror or TypeElement

I don't understand how I can retrieve the Enum values in an annotation processor.

My annotation is a custom Java Bean Validation annotation:

  @StringEnumeration(enumClass = UserCivility.class)
  private String civility;

On my annotation processor, I can access to instances of these:

javax.lang.model.element.AnnotationValue
javax.lang.model.type.TypeMirror
javax.lang.model.element.TypeElement

I know it contains the data about my enum since I can see that in debug mode. I also see ElementKind == Enum

But I want to get all the names for that Enum, can someone help me please.


Edit: I don't have access to the Class object of this Enum, because we are in an annotation processor, and not in standart Java reflection code. So I can't call Class#getEnumConstants() or EnumSet.allOf(MyEnum.class) unless you tell me how I can get the Class object from the types mentioned above.

I found a solution (this uses Guava):

class ElementKindPredicate<T extends Element> implements Predicate<T> {
    private final ElementKind kind;
    public ElementKindPredicate(ElementKind kind) {
      Preconditions.checkArgument(kind != null);
      this.kind = kind;
    }
    @Override
    public boolean apply(T input) {
      return input.getKind().equals(kind);
    }
}

private static final ElementKindPredicate ENUM_VALUE_PREDICATE = new ElementKindPredicate(ElementKind.ENUM_CONSTANT);

public static List<String> getEnumValues(TypeElement enumTypeElement) {
    Preconditions.checkArgument(enumTypeElement.getKind() == ElementKind.ENUM);
    return FluentIterable.from(enumTypeElement.getEnclosedElements())
        .filter(ENUM_VALUE_PREDICATE)
        .transform(Functions.toStringFunction())
        .toList();
}

The answer given by Sebastian is correct, but if you're using Java 8 or above, you can use the following (cleaner) approach than using Google Guava.

List<String> getEnumValues(TypeElement enumTypeElement) {
    return enumTypeElement.getEnclosedElements().stream()
            .filter(element -> element.getKind().equals(ElementKind.ENUM_CONSTANT))
            .map(Object::toString)
            .collect(Collectors.toList());
}

Here's a complete example. Note the use of getEnumConstants on the enum values.

public class Annotate {

    public enum MyValues {
        One, Two, Three     
    };

    @Retention(RetentionPolicy.RUNTIME)
    public @interface StringEnumeration {   
        MyValues enumClass();           
    }

    @StringEnumeration(enumClass = MyValues.Three)
    public static String testString = "foo";

    public static void main(String[] args) throws Exception {

        Class<Annotate> a = Annotate.class; 
        Field f = a.getField("testString");
        StringEnumeration se = f.getAnnotation(StringEnumeration.class);
        if (se != null) {
            System.out.println(se.enumClass());

            for( Object o : se.enumClass().getClass().getEnumConstants() ) {
                System.out.println(o);
            }

        }                                   
    }
}

This will print out:

Three
One
Two
Three

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM