Подтвердить что ты не робот

Получить аннотации для переменной типа перечисления

У меня есть переменная non null (например, en1) типа Enum. Возникает вопрос: как получить аннотации, связанные с константой перечисления, на которые ссылается переменная en1?

4b9b3361

Ответ 1

Как я уже сказал:

en1.getClass().getField(((Enum)en1).name()).getAnnotations();

Чтобы быть яснее:

String name = e.name(); // Enum method to get name of presented enum constant
Annotation[] annos = e.getClass().getField(name).getAnnotations(); // Classical reflection technique

В этом случае нам не нужно знать действительный класс en1.

См. также: замечание об обфускационном случае.

Ответ 2

Попробуйте это (отражение java):

String field = En.AAA.name();
En.class.getField(field).getAnnotations();

Он должен получить аннотации из AAA.

EDIT:

Как предположил автор:

en1.getClass().getField(((Enum)en1).name()).getAnnotations(); 

Работает для него:)

Ответ 3

Я только что прочитал из вашего комментария, что вы уже нашли ответ. Я просто хотел отметить для других людей, заинтересованных в том, что для того, чтобы это сработало, эти аннотации должны были быть объявлены с правильной политикой хранения, например:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Anno1 {
   // ...
}

Без этого они не будут доступны во время выполнения.

Дальнейшее чтение:

Ответ 4

Если вы используете обфускатор, такой как Proguard, вы можете обнаружить, что поля перечисления были переименованы, а .name() все еще возвращает исходное имя поля. Например, это перечисление...

enum En {
    FOO,
    BAR
}

... станет после ProGuarding...

enum En {
    a,
    b
}

... но En.FOO.name() все равно вернет "FOO", что приведет к ошибке getField(En.FOO.name()), потому что он ожидает, что поле будет называться "a".

Если вы хотите получить Field для определенного поля перечисления из обфускационного кода, вы можете сделать это:

for (Field field : En.class.getDeclaredFields()) {
    if (field.isEnumConstant()) {
        try {
            if (en1 == field.get(null)) {
                Annotation[] annotations = field.getAnnotations();
            }
        } catch (IllegalAccessException e) {
            // 
        }
    }
}

Ответ 5

В дополнение к существующим ответам, если вы контролируете класс enum (можете его редактировать), вы можете просто добавить метод к перечислению для извлечения требуемой аннотации i.e.

AnnotationClass getAnnotation(){
   Field field = this.getClass().getField(this.name());
   return field.getAnnotation(AnnotationClass.class);       
}

или все его аннотации:

Annotation[] getAnnotations(){
   Field field = this.getClass().getField(this.name());
   return field.getAnnotations();
}

Отрегулируйте приведенный выше код для обработки исключений (NoSuchFieldException и SecurityException).