Y a-t-il quelque chose comme un héritage D'Annotation en java?

j'explore les annotations et en suis arrivé à un point où certaines annotations semblent avoir une hiérarchie entre elles.

j'utilise des annotations pour générer du code en arrière-plan pour les cartes. Il y a différents types de cartes (donc différents codes et annotations) mais il y a certains éléments qui sont communs entre eux comme un nom.

@Target(value = {ElementType.TYPE})
public @interface Move extends Page{
 String method1();
 String method2();
}

et ce serait L'Annotation commune:

@Target(value = {ElementType.TYPE})
public @interface Page{
 String method3();
}

Dans l'exemple ci-dessus je m'attendrais à ce que Move hérite de la method3 mais je reçois un avertissement disant que s'étend n'est pas valide avec des annotations. J'essayais d'avoir une Annotation s'étend une base commune mais qui ne fonctionne pas. Si, c'est possible ou c'est juste un problème de conception?

85
demandé sur javydreamercsw 2011-10-14 03:16:40

3 réponses

malheureusement, non. Apparemment, cela a quelque chose à voir avec les programmes qui lisent les annotations sur une classe sans les charger complètement. Voir pourquoi N'est-il pas possible d'étendre les annotations en Java?

cependant, les types héritent les annotations de leur superclasse si ces annotations sont @Inherited .

aussi, à moins que vous n'ayez besoin de ces méthodes pour interagir, vous pouvez simplement empiler annotations sur votre classe:

@Move
@Page
public class myAwesomeClass {}

y a-t-il une raison qui ne marcherait pas pour vous?

56
répondu andronikus 2017-05-23 12:17:55

vous pouvez annoter votre annotation avec une annotation de base au lieu d'héritage. C'est utilisé dans le cadre de ressort .

pour donner un exemple

@Target(value = {ElementType.ANNOTATION_TYPE})
public @interface Vehicle {
}

@Target(value = {ElementType.TYPE})
@Vehicle
public @interface Car {
}

@Car
class Foo {
}

vous pouvez alors vérifier si une classe est annotée avec Vehicle en utilisant AnnotationUtils du ressort :

Vehicle vehicleAnnotation = AnnotationUtils.findAnnotation (Foo.class, Vehicle.class);
boolean isAnnotated = vehicleAnnotation != null;

cette méthode est appliquée comme suit:

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 aussi contient des méthodes supplémentaires de recherche d'annotations sur les méthodes et autres éléments annotés. La classe des ressorts est aussi assez puissante pour chercher par des méthodes pontées, des approximations, et d'autres cas de coin, en particulier ceux rencontrés au printemps.

41
répondu Grygoriy Gonchar 2016-10-24 10:11:52

En plus de Grygoriys réponse de l'annotation annotations.

vous pouvez vérifier par exemple les méthodes pour contenir une annotation @qualificatif (ou une annotation annotée avec @qualificatif) par cette boucle:

for (Annotation a : method.getAnnotations()) {
    if (a.annotationType().isAnnotationPresent(Qualifier.class)) {
        System.out.println("found @Qualifier annotation");//found annotation having Qualifier annotation itself
    }
}

ce que vous faites essentiellement, c'est d'obtenir toutes les annotations présentes sur la méthode et de ces annotations vous obtenez leurs types et vérifiez ces types s'ils sont annotés avec @Qualifier. Votre annotation doit être Cible.Annotation_type est aussi activé pour que cela fonctionne.

5
répondu philnate 2015-06-03 14:33:16