How does Java method annotation work in conjunction with method overrides?

I have a parent class Parent and a child class Child defined this way:

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

If I get a Method link to Child::foo , will childFoo.getAnnotation(MyAnnotation.class) give me @MyAnnotation ? Or will it be null ?

I'm more interested in knowing how or with annotation it works with Java inheritance.

+54
java override inheritance annotations
Apr 10 2018-12-12T00:
source share
4 answers

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

Inheritance of annotations

It is important to understand the rules related to inheritance of annotations, as they relate to matching join points based on the presence or absence of annotations.

By default, annotations are not inherited. Given the following program

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

Then Sub does not have MyAnnotation annotation, and Sub.foo() not @Oneway , despite the fact that it overrides Super.foo() , which is.

If the annotation type has the @Inherited meta annotation, then the annotation of this type in the class will cause the annotation to be inherited by subclasses. So, in the example above, if the MyAnnotation type had the @Inherited attribute, then Sub would have the MyAnnotation annotation.

@Inherited annotations are not inherited when using anything other than a type to annotate. A type that implements one or more interfaces never inherits any annotations from the interfaces it implements.

+57
Apr 10 '12 at 3:10
source share

You have already found your answer: JDK does not provide for the inheritance of annotation methods.

But climbing a superclassical chain in search of annotated methods is also easy to implement:

 /** * 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<? extends Annotation> 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); } 
+9
May 20 '12 at 13:20
source share

While the answer to the question asked is that Java Method.getAnnotation() does not consider overridden methods, it is sometimes useful to find these annotations. Here is a more complete version of Saintali's answer that I am currently using:

 public static <A extends Annotation> A getInheritedAnnotation( Class<A> annotationClass, AnnotatedElement element) { A annotation = element.getAnnotation(annotationClass); if (annotation == null && element instanceof Method) annotation = getOverriddenAnnotation(annotationClass, (Method) element); return annotation; } private static <A extends Annotation> A getOverriddenAnnotation( Class<A> 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 extends Annotation> A getOverriddenAnnotationFrom( Class<A> 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; } } 
+2
Jun 24 '13 at 17:08
source share

Using Spring Core you can enable with

AnnotationUtils.java

+2
May 08 '15 at 1:07
source share



All Articles