У меня есть переменная non null
(например, en1
) типа Enum
. Возникает вопрос: как получить аннотации, связанные с константой перечисления, на которые ссылается переменная en1
?
Получить аннотации для переменной типа перечисления
Ответ 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).