JB Header
Java 8 Repeating Annotations Tutorial using @Repeatable with examples
This article explains what are Java 8 Repeating Annotations, how to define Repeating Annotations using the @Repeatable annotation and how these are handled internally. Lastly, it also takes a look at how Class.java has been changed in Java 8 to handle Repeating Annotations. What is the Repeating Annotations feature As the name suggests, Repeating Annotations imply that a particular annotation is applied multiple times to a declaration.
For example: Lets say there is an annotation @Color with an attribute name of type String. Let us apply @Color annotation multiple times to another class Shirt as shown below -
Repeating Annotations example
@interface Color {
  String name();
}
@Color(name = "red") 
@Color(name = "blue") 
@Color(name = "green")//@Color annotation repeated 3 times
class Shirt {
}
In the above code @Color is the Repeating Annotation.
Prior to Java 8 Till Java 7, Repeating Annotations defined in the above way would have given a compiler error -
Duplicate annotation @Color ....

However, Java 8 onwards Repeating Annotations are allowed, but we need to define an annotation in a specific way to make it repeatable. Lets see how... How to Define Repeating Annotations in Java 8 Defining a repeating annotation involves two steps:
  1. Annotate Repeating Annotation with @Repeatable: Mark the annotation which can be repeated with @Repeatable annotation. This is a meta-annotation as it annotates an annotation.
  2. Create a container annotation: Create an annotation which has an attribute which is an array of the Repeating Annotation type.
Let us now apply the above two rules to make the @Color annotation repeatable. The implementation would look like this -
Defining @Color as a repeatable annotation
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 @Repeatable(Colors.class)
 @interface Color {
   String name();
 }
 @Retention(RetentionPolicy.RUNTIME)
 @interface Colors {
   Color[] value();
 }
 @Color(name = "red") @Color(name = "blue") @Color(name = "green")
 class Shirt {
 }
Where, Colors is the Container Annotation.
Changes in Class.java in Java 8 to Support Repeating Annotations Class.java, from Java 8 onwards, supports a new method getAnnotationsByType(<Annotation-class>) method which returns an array of Annotation-Class type. Lets see an example usage of this new method using @Color, @Colors & Shirt class defined earlier -
Example showing usage of Class.getAnnotationsByType() method
public class RepeatingAnnotations {
  public static void main(String args[]) {
   Color[] colorArray = Shirt.class.getAnnotationsByType(Color.class);
   for (Color color : colorArray) {
    System.out.println(color.name());
   }
  }
 }
 OUTPUT of the above code
red
blue
green
Note - To get the annotation information at runtime do annotate @Colors annotation with @Retention(RetentionPolicy.RUNTIME) annotation. How Java 8 handles Repeating Annotations internally Java 8 internally treats this Repeating Annotation as an instance of @Colors holding an array of @Color. The fact that we do not use @Colors when we annotate definition of Shirt class is just easing the syntax for the developer. Internally, the compiler treats it as a @Colors container annotation with an array of @Color. Summary We looked at what are Repeating Annotations, how to define & use Repeating Annotations, saw changes done in Class.java to support Repeating Annotations, and finally, learned how Java 8 internally handles Repeating Annotations.