Until Java 8, two instances of the same annotation could not be applied to a single element. The standard workaround was to use a container annotation holding an array of some other annotation:
// Author.java @Retention(RetentionPolicy.RUNTIME) public @interface Author { String value(); } // Authors.java @Retention(RetentionPolicy.RUNTIME) public @interface Authors { Author[] value(); } // Test.java @Authors({ @Author("Mary"), @Author("Sam") }) public class Test { public static void main(String[] args) { Author[] authors = Test.class.getAnnotation(Authors.class).value(); for (Author author : authors) { System.out.println(author.value()); // Output: // Mary // Sam } } }
Version ≥ Java SE 8
Java 8 provides a cleaner, more transparent way of using container annotations, using the @Repeatable annotation. First we add this to the Author class:
@Repeatable(Authors.class)
This tells Java to treat multiple @Author annotations as though they were surrounded by the @Authors container. We can also use Class.getAnnotationsByType() to access the @Author array by its own class, instead of through its container:
@Author("Mary") @Author("Sam") public class Test { public static void main(String[] args) { Author[] authors = Test.class.getAnnotationsByType(Author.class); for (Author author : authors) { System.out.println(author.value()); // Output: // Mary // Sam } } }
By default class annotations do not apply to types extending them. This can be changed by adding the @Inherited annotation to the annotation definition
Example
Consider the following 2 Annotations:
@Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InheritedAnnotationType { }
and
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface UninheritedAnnotationType { }
If three classes are annotated like this:
@UninheritedAnnotationType class A { } @InheritedAnnotationType class B extends A { } class C extends B { }
running this code
System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class)); System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class)); System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class)); System.out.println("_________________________________"); System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class)); System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class)); System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));
will print a result similar to this (depending on the packages of the annotation):
null @InheritedAnnotationType() @InheritedAnnotationType() _________________________________ @UninheritedAnnotationType() null null
Note that annotations can only be inherited from classes, not interfaces.
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions