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.

 

Digiprove sealCopyright © 2014-2019 JavaBrahman.com, all rights reserved.