Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do Java method annotations work in conjunction with method overriding?

I have a parent class Parent and a child class Child, defined thus:

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

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

I'm interested more generally in how or whether annotation works with Java inheritance.

like image 772
Travis Webb Avatar asked Apr 10 '12 03:04

Travis Webb


People also ask

Which annotation is used in method overriding?

The @Override annotation is a standard Java annotation that was first introduced in Java 1.5. The @Override annotation denotes that the child class method overrides the base class method.

Is it compulsory to add @override annotation before each overriding method?

@Override annotation is used when we override a method in sub class. Generally novice developers overlook this feature as it is not mandatory to use this annotation while overriding the method.

Why do we use the annotation @override when overriding an inherited method?

@Override @Override annotation informs the compiler that the element is meant to override an element declared in a superclass. Overriding methods will be discussed in Interfaces and Inheritance. While it is not required to use this annotation when overriding a method, it helps to prevent errors.

Are method annotations inherited Java?

Because there is no multiple inheritance in Java, annotations on interfaces cannot be inherited.


2 Answers

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

Annotation Inheritance

It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching 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 the MyAnnotation annotation, and Sub.foo() is not an @Oneway method, despite the fact that it overrides Super.foo() which is.

If an annotation type has the meta-annotation @Inherited then an annotation of that type on a class will cause the annotation to be inherited by sub-classes. 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 used to annotate anything other than a type. A type that implements one or more interfaces never inherits any annotations from the interfaces it implements.

like image 79
trutheality Avatar answered Oct 17 '22 00:10

trutheality


You found your answer already: there is no provision for method-annotation inheritance in the JDK.

But climbing the super-class 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); } 
like image 28
Saintali Avatar answered Oct 17 '22 01:10

Saintali