¿Cómo funcionan las anotaciones del método Java junto con la anulación de método?

Tengo un padre de clase primaria y un hijo de clase Child , definidos así:

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

Si childFoo.getAnnotation(MyAnnotation.class) una referencia de Method a Child::foo , ¿ childFoo.getAnnotation(MyAnnotation.class) dará childFoo.getAnnotation(MyAnnotation.class) ? ¿O será null ?

Me interesa más en general cómo o si la anotación funciona con la herencia de Java.

Copiado textualmente de http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html#annotation-inheritance :

Herencia de anotación

Es importante comprender las reglas relacionadas con la herencia de las anotaciones, ya que tienen relación con la coincidencia de puntos de unión en función de la presencia o ausencia de anotaciones.

Por defecto, las anotaciones no son heredadas. Dado el siguiente progtwig

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

Entonces Sub no tiene la anotación MyAnnotation , y Sub.foo() no es un método @Oneway , a pesar de que anula Super.foo() que es.

Si un tipo de anotación tiene la @Inherited , una anotación de ese tipo en una clase hará que la anotación sea heredada por las subclases. Entonces, en el ejemplo anterior, si el tipo MyAnnotation tenía el atributo @Inherited , entonces Sub tendría la anotación MyAnnotation .

@Inherited anotaciones heredadas no se heredan cuando se usan para anotar cualquier cosa que no sea un tipo. Un tipo que implementa una o más interfaces nunca hereda ninguna anotación de las interfaces que implementa.

Ya encontraste tu respuesta: no hay ninguna provisión para la herencia de anotación de método en el JDK.

Pero escalar la cadena de las superclase en busca de métodos anotados también es fácil de implementar:

 /** * 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 puedes resolver con

AnnotationUtils.java

Si bien la respuesta a la pregunta formulada es que Method.getAnnotation() Java no tiene en cuenta los métodos anulados, a veces es útil encontrar estas anotaciones. Aquí hay una versión más completa de la respuesta de Saintali que estoy usando actualmente:

 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 superclasses 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; } }