Динамическое преобразование типов аннотаций Java

У меня есть 2 типа аннотаций Java, скажем, XA и YA. У обоих есть метод(). Я разбираю исходный код и получаю объект Annotation. Теперь я хотел бы динамически привести аннотацию к ее реальному типу, чтобы иметь возможность вызывать метод(). Как я могу сделать это без оператора instanceof? Я действительно хочу избежать источника, похожего на переключатель. Мне нужно что-то вроде этого:

Annotation annotation = getAnnotation(); // I recieve the Annotation object here
String annotationType = annotation.annotationType().getName();

?_? myAnnotation = (Class.forName(annotationType)) annotation;
annotation.method(); // this is what I need, get the method() called

?_? означает, что я понятия не имею, каким будет тип myAnnotation. Я не могу использовать базовый класс для своих аннотаций XA и YA, поскольку наследование в аннотациях не разрешено. Или можно как-то сделать?

Спасибо за любое предложение или помощь.


person Pavel S.    schedule 29.04.2011    source источник


Ответы (2)


Почему бы вам не использовать типизированный способ получения вашей аннотации?

final YourAnnotationType annotation = classType.getAnnotation(YourAnnotationType.class);
annotation.yourMethod();

Если ваша аннотация не может быть найдена, возвращается null.

Обратите внимание, что это также работает с полями и методами.

person faulomi    schedule 29.04.2011
comment
Это не решает мою проблему. Мне нужно объявить эту строку для каждого MyAnnotationType, который я использую. classType.getAnnotation(YourAnnotationType.class); Так что это снова будет выглядеть как переключатель. - person Pavel S.; 29.04.2011

Один из способов — вызвать метод динамически, используя его имя:

Annotation annotation = getAnnotation();
Class<? extends Annotation> annotationType = annotation.annotationType();
Object result = annotationType.getMethod("method").invoke(annotation);

Этот подход довольно рискован и полностью ставит под угрозу рефакторинг кода, если это необходимо.

person Damian Leszczyński - Vash    schedule 29.04.2011
comment
Прекрасно работает! Я получил атрибут имени из аннотации @Table, извлекая имя таблицы из annotation.toSring() с помощью простого регулярного выражения, но ваше решение более элегантно. - person Jose Rui Santos; 24.08.2016