In che modo le annotazioni del metodo Java funzionano in combinazione con l’override del metodo?

Ho un genitore della class Parent e una class Child , così definito:

 class Parent { @MyAnnotation("hello") void foo() { // implementation irrelevant } } class Child { @Override foo() { // implementation irrelevant } } 

Se ottengo un riferimento al Method per Child::foo , will childFoo.getAnnotation(MyAnnotation.class) mi dà @MyAnnotation ? O sarà null ?

Mi interessa in generale come e se l’annotazione funziona con l’ereditarietà di Java.

Copiato verbatim da http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html#annotation-inheritance :

Ereditarietà delle annotazioni

È importante comprendere le regole relative all’ereditarietà delle annotazioni, poiché queste influiscono sulla corrispondenza dei punti di join in base alla presenza o assenza di annotazioni.

Di default le annotazioni non sono ereditate. Dato il seguente programma

  @MyAnnotation class Super { @Oneway public void foo() {} } class Sub extends Super { public void foo() {} } 

Quindi Sub non ha l’annotazione MyAnnotation e Sub.foo() non è un metodo @Oneway , nonostante sostituisca Super.foo() che è.

Se un tipo di annotazione ha la meta-annotazione @Inherited allora un’annotazione di quel tipo su una class farà sì che l’annotazione venga ereditata dalle sottoclassi. Quindi, nell’esempio sopra, se il tipo MyAnnotation aveva l’attributo @Inherited , Sub avrebbe l’annotazione MyAnnotation .

@Inherited annotazioni non ereditate non vengono ereditate quando vengono utilizzate per annotare qualcosa di diverso da un tipo. Un tipo che implementa una o più interfacce non eredita mai alcuna annotazione dalle interfacce implementate.

Hai già trovato la tua risposta: non esiste alcuna disposizione per l’ereditarietà delle annotazioni sul metodo nel JDK.

Ma scalare la catena super-class alla ricerca di metodi annotati è anche facile da implementare:

 /** * Climbs the super-class chain to find the first method with the given signature which is * annotated with the given annotation. * * @return A method of the requested signature, applicable to all instances of the given * class, and annotated with the required annotation * @throws NoSuchMethodException If no method was found that matches this description */ public Method getAnnotatedMethod(Class annotation, Class c, String methodName, Class... parameterTypes) throws NoSuchMethodException { Method method = c.getMethod(methodName, parameterTypes); if (method.isAnnotationPresent(annotation)) { return method; } return getAnnotatedMethod(annotation, c.getSuperclass(), methodName, parameterTypes); } 

Usando Spring Core puoi risolvere con

AnnotationUtils.java

Mentre la risposta alla domanda è come se Method.getAnnotation() di Java non considera metodi sovrascritti, a volte è utile trovare queste annotazioni. Ecco una versione più completa della risposta di Saintali che sto attualmente utilizzando:

 public static  A getInheritedAnnotation( Class annotationClass, AnnotatedElement element) { A annotation = element.getAnnotation(annotationClass); if (annotation == null && element instanceof Method) annotation = getOverriddenAnnotation(annotationClass, (Method) element); return annotation; } private static  A getOverriddenAnnotation( Class annotationClass, Method method) { final Class methodClass = method.getDeclaringClass(); final String name = method.getName(); final Class[] params = method.getParameterTypes(); // prioritize all superclasss over all interfaces final Class superclass = methodClass.getSuperclass(); if (superclass != null) { final A annotation = getOverriddenAnnotationFrom(annotationClass, superclass, name, params); if (annotation != null) return annotation; } // depth-first search over interface hierarchy for (final Class intf : methodClass.getInterfaces()) { final A annotation = getOverriddenAnnotationFrom(annotationClass, intf, name, params); if (annotation != null) return annotation; } return null; } private static  A getOverriddenAnnotationFrom( Class annotationClass, Class searchClass, String name, Class[] params) { try { final Method method = searchClass.getMethod(name, params); final A annotation = method.getAnnotation(annotationClass); if (annotation != null) return annotation; return getOverriddenAnnotation(annotationClass, method); } catch (final NoSuchMethodException e) { return null; } }