Есть ли что-то вроде наследования аннотаций в java?
Я изучаю аннотации и пришел к точке, где некоторые аннотации, кажется, имеют иерархию среди них.
Я использую аннотации для генерации кода в фоновом режиме для карт. Существуют различные типы карт (таким образом, различные коды и аннотации), но есть определенные элементы, которые являются общими среди них, как имя.
@Target(value = {ElementType.TYPE})
public @interface Move extends Page{
String method1();
String method2();
}
и это будет общая Аннотация:
@Target(value = {ElementType.TYPE})
public @interface Page{
String method3();
}
в приведенном выше примере я бы ожидал, что Move унаследует method3 но я получаю предупреждение о том, что extends недопустимо с аннотациями. Я пытался иметь аннотацию, расширяющую общую базу, но это не работает. Это вообще возможно или это просто проблема дизайна?
3 ответа:
к сожалению, нет. По-видимому, это имеет какое-то отношение к программам, которые читают аннотации в классе, не загружая их полностью. Смотрите почему невозможно расширить аннотации в Java?
однако типы наследуют аннотации своего суперкласса, если эти аннотации
@Inherited
.кроме того, если вам не нужны эти методы для взаимодействия, вы можете просто сложить аннотации в свой класс:
@Move @Page public class myAwesomeClass {}
Is есть какая-то причина, которая не сработает для вас?
вы можете аннотировать свою аннотацию с помощью базовой аннотации вместо наследования. Это используется в Spring framework.
к примеру
@Target(value = {ElementType.ANNOTATION_TYPE}) public @interface Vehicle { } @Target(value = {ElementType.TYPE}) @Vehicle public @interface Car { } @Car class Foo { }
затем вы можете проверить, если класс аннотируется
Vehicle
используя весной: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 также достаточно силен для поиска через мостовые методы, прокси и другие угловые случаи, особенно те, которые встречаются весной.
в дополнение к ответу Григория аннотирования аннотаций.
вы можете проверить, например, методы для содержания аннотации @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. Ваша аннотация должна быть целевой.Annotation_type включен также, чтобы получить это рабочий.