Annotations   «Prev  Next»

Inherited and Repeatable Annotations

Question: What does the inherited Annotation mean when used on an Annotation.
Create 2 annotations in the Annotations package.
MyFirstInheritedAnnotation
For the code below, we have annotated the notation with @Inherited.
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFirstInheritedAnnotation {
}

@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MySecondInheritedAnnotation {
}

These 2 annotations are identical with the exception of a different name. Place this code below the main method.
@MyFirstInheritedAnnotation
abstract class ParentClass {

    @MyFirstInheritedAnnotation
    public abstract void abstractMethod();
}

@MySecondInheritedAnnotation
interface SomeInterface {

    @MySecondInheritedAnnotation
    void interfaceMethod();
}

In order to make this compile
public class TestingAnnotatedClasses extends ParentClass
  implements SomeInterface{

we have to add some methods.
Output of program after running it
"C:\Program Files\Java\jdk-11.0.8\bin\java.exe" "-javaagent:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2020.2.3\lib\idea_rt.jar=59041:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2020.2.3\bin" -Dfile.encoding=UTF-8 -classpath D:\AnnotationsProject\out\production\AnnotationsProject TestingAnnotatedClasses
Class Annotation: @annotations.MyRuntimeAnnotation(author="Thomas Hauck", version=1.1, description="This class is used for testing annotations")
Process finished with exit code 0
Question: Are Annotations inherited? Change the reflected methods names from getDeclaredAnnotations to getAnnotations.
Go into our showAnnotations mehod This the output after changing the method
"C:\Program Files\Java\jdk-11.0.8\bin\java.exe" "-javaagent:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2020.2.3\lib\idea_rt.jar=60102:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2020.2.3\bin" 
-Dfile.encoding=UTF-8 -classpath D:\AnnotationsProject\out\production\AnnotationsProject TestingAnnotatedClasses
Class Annotation: @annotations.MyFirstInheritedAnnotation()
Class Annotation: @annotations.MyRuntimeAnnotation(author="Thomas Hauck", version=1.1, description="This class is used for testing annotations")
Process finished with exit code 0 MyFirstInheritedAnnotation, which annotated the parent class and not the TestingAnnotatedClasses is considered an Annotation of the TestingAnnotatedClasses and is inherited if the inherited annotation is used on the Annotation Declaration.
The inherited annotation is inherited at the type level,
Class Annotation: @annotations.MyFirstInheritedAnnotation()
MyFirstInheritedAnnotation only appears for the class and not for the method. Inherited and Repeatable Annotations Restating this because this is a perfect candidate for an exam question. Annotations annotated with @inherited will only get inherited from some superclass (and not through an interface) and only when declared at the class level (not four methods, fields, parameters) A Repeatable Annotation requires 2 annotations, the annotation that you want to be repeated, and a container annotation which has as its value, an array of the repeatable annotation.
This annotation
public @interface MyRepeatableAnnotations {
    MyRepeatableAnnotation[] value();
}
will not compile until we create the second container annotation. MyRepeatableAnnotations
We have an annotation that we want to be repeated and a container Annotation which has as its value an array of the Repeatable Annotation.
// --Marker Annotation,  Repeatable
@MyRepeatableAnnotation

contains no parameter and has a default value of 0.
Go back to the Annotation Processor at the top of the class. There are some situations where you want to apply the same annotation to a declaration or type use. As of the Java SE 8 release, repeating annotations enable you to do this.
// No parameter and 1 parameter which will change the behavior
@MyRepeatableAnnotation
@MyRepeatableAnnotation(10)

D:\AnnotationsProject\out\production\AnnotationsProject >javac -d . -cp . -processor AnnotationProcessor ../../../src/TestingAnnotatedClasses.java
CLASS unnamed package.TestingAnnotatedClasses is annotated with annotations.MyFirstInheritedAnnotation
CLASS unnamed package.ParentClass is annotated with annotations.MyFirstInheritedAnnotation
METHOD ParentClass.abstractMethod() is annotated with annotations.MyFirstInheritedAnnotation
CLASS unnamed package.TestingAnnotatedClasses is annotated with annotations.MyRepeatableAnnotations
METHOD TestingAnnotatedClasses.printRuntimeAnnotations() is annotated with annotations.MySourceAnnotation
INTERFACE unnamed package.SomeInterface is annotated with annotations.MySecondInheritedAnnotation
METHOD SomeInterface.interfaceMethod() is annotated with annotations.MySecondInheritedAnnotation
CLASS unnamed package.TestingAnnotatedClasses is annotated with annotations.MyRuntimeAnnotation
FIELD TestingAnnotatedClasses.myField is annotated with annotations.MyClassAnnotation

Inherited and Repeatable Annotations

  1. Annotation categories based on element values:
    Marker, Single Element, and Normal annotations
  2. Annotation categories based on retention policy:
    SOURCE, CLASS, and RUNTIME
  3. I have provided a sample annotation processor to locate annotations of any retention policy and do something in this case just print information to the console
  4. I have provided sample code to show you how to use reflection methods to query runtime annotations.

  1. You can see Class and Runtime Annotations in a verbose listing of javap on the class file that declares the annotations.
  2. Create custom annotations that:
  1. Do not have elements
  2. Have multiple elements
  3. Have a single element named value with a default value.
  4. Have Annotations themselves.

Annotations which apply to Annotations

  1. @Target - Defines which java elements can be annotated with the annotation.
  2. @Retention - Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.
  3. @Documented - Defines if the annotation information will be part of the published API.
  4. @Inherited - remember that an annotation annotated with this annotation is only inherited if the annotation is applies to a class and the class is the superclass, directly or indirectly, of another class.
  5. @Repeatable - to make an annotation repeatable, you will need to create two annotations, one is the repeatable annotation using the @Repeatable and the other is a container for an array of the Repeatable annotation.