Есть ли что-то вроде аннотации Inheritance в java?
Я изучаю аннотации и дошел до точки, где некоторые аннотации, похоже, имеют иерархию среди них.
Я использую аннотации для генерации кода в фоновом режиме для Карт. Существуют разные типы карт (например, разные коды и аннотации), но есть некоторые элементы, которые являются общими среди них, как имя.
@Target(value = {ElementType.TYPE})
public @interface Move extends Page{
String method1();
String method2();
}
И это будет общая аннотация:
@Target(value = {ElementType.TYPE})
public @interface Page{
String method3();
}
В приведенном выше примере я ожидал бы Move для наследования метода3, но я получаю предупреждение о том, что extends недействителен с аннотациями. Я пытался, чтобы аннотация распространяла общую базовую, но это не работает. Возможно ли это или просто проблема дизайна?
Ответы
Ответ 1
К сожалению, нет. По-видимому, это имеет какое-то отношение к программам, которые читают аннотации в классе, не загружая их полностью. См. Почему нельзя расширять аннотации в Java?
Однако типы наследуют аннотации их суперкласса, если эти аннотации @Inherited
.
Кроме того, если вам не нужны эти методы для взаимодействия, вы можете просто складывать аннотации в своем классе:
@Move
@Page
public class myAwesomeClass {}
Есть ли какая-то причина, которая не сработает для вас?
Ответ 2
Вы можете аннотировать свою аннотацию базовой аннотацией вместо наследования. Это используется в Spring рамках.
Чтобы привести пример
@Target(value = {ElementType.ANNOTATION_TYPE})
public @interface Vehicle {
}
@Target(value = {ElementType.TYPE})
@Vehicle
public @interface Car {
}
@Car
class Foo {
}
Затем вы можете проверить, был ли класс аннотирован с помощью Vehicle
, используя Spring AnnotationUtils:
Vehicle vehicleAnnotation = AnnotationUtils.findAnnotation (Foo.class, Vehicle.class);
boolean isAnnotated = vehicleAnnotation != null;
Этот метод реализуется как:
public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
return findAnnotation(clazz, annotationType, new HashSet<Annotation>());
}
@SuppressWarnings("unchecked")
private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType, Set<Annotation> visited) {
try {
Annotation[] anns = clazz.getDeclaredAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() == annotationType) {
return (A) ann;
}
}
for (Annotation ann : anns) {
if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
A annotation = findAnnotation(ann.annotationType(), annotationType, visited);
if (annotation != null) {
return annotation;
}
}
}
}
catch (Exception ex) {
handleIntrospectionFailure(clazz, ex);
return null;
}
for (Class<?> ifc : clazz.getInterfaces()) {
A annotation = findAnnotation(ifc, annotationType, visited);
if (annotation != null) {
return annotation;
}
}
Class<?> superclass = clazz.getSuperclass();
if (superclass == null || Object.class == superclass) {
return null;
}
return findAnnotation(superclass, annotationType, visited);
}
AnnotationUtils
также содержит дополнительные методы для поиска аннотаций по методам и другим аннотированным элементам. Класс Spring также достаточно эффективен для поиска по мостовым методам, прокси и другим угловым шкафам, особенно тем, которые встречаются в Spring.
Ответ 3
В дополнение к ответу Grygoriys аннотаций аннотаций.
Вы можете проверить, например. методы для добавления аннотации @Qualifier (или аннотации, аннотированной с помощью @Qualifier) в этом цикле:
for (Annotation a : method.getAnnotations()) {
if (a.annotationType().isAnnotationPresent(Qualifier.class)) {
System.out.println("found @Qualifier annotation");//found annotation having Qualifier annotation itself
}
}
То, что вы в основном делаете, состоит в том, чтобы получить все аннотации, присутствующие в методе, и тех аннотаций, которые вы получили, и проверить эти типы, если они аннотируются с помощью @Qualifier. Ваша аннотация должна быть Target.Annotation_type включен также, чтобы заставить это работать.