Java Repeating Annotations

Another new JDK 8 annotation feature enables an annotation to be repeated on the same element. This is called as repeating annotations.

For an annotation to be repeatable, it must be annotated with the @Repeatable annotation, defined in the java.lang.annotation. Its value field specifies the container type for the repeatable annotation. The container is specified as an annotation for which the value field is an array of the repeatable annotation type. Thus, to create a repeatable annotation, you must create a container annotation and then specify that annotation type as an argument to the @Repeatable annotation.

Java Repeating Annotation Example

To access repeatable annotations using a method such as getAnnotation(), you will use the container annotation, not the repeatable annotation. The following program shows this approach. It converts the version of the MyAnnotat shown previously into a repeatable annotation and demonstrates its use.

/* Java Program Example - Java Repeating Annotations
*  This program demonstrate a repeated annotation */

import java.lang.annotation.*;
import java.lang.reflect.*;

/* make MyAnnotat repeatable */
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnos.class)
@interface MyAnnotat {
   String str() default = "Testing";
   int val() default 9000;
}

/* this is the container annotation */
@Retention(RetentionPolicy.RUNTIME)
@interface MyRepeatedAnnos {
   MyAnnotat[] value();
}

class RepeatAnnotat {

   /* repeat MyAnnotat on myMethod() */
   @MyAnnotat(str = "First annotation", val = -1)
   @MyAnnotat(str = "Second annotation", val = 100);
   public static void myMethod(String str, int i)
   {
      RepeatAnnotat obj = new RepeatAnnotat();
      
      try {
         Class<?> c = obj.getClass();
         
         /* obtain the annotations for myMethod() */
         Method m = c.getMethod("myMethod", String.class, int.class);
         
         /* display the repeated MyAnnotat annotations */
         Annotation anno = m.getAnnotation(MyRepeatedAnnos.class);
         System.out.println(anno);
         
      } catch(NoSuchMethodException exc) {
         System.out.println("Method not found..!!");
      }
   }
   
   public static void main(String args[])
   {
   
      myMethod("test", 10);
      
   }
}

The output of the above Java program is shown here :

@MyRepeatedAnnos(value=[@MyAnnotat(str=First annotation, val=-1),
@MyAnnotat(str=Second annotation, val=100)])

As explained, in order for MyAnnotat to be repeatable, it must be annotated with @Repeatable annotation, which specifies its container annotation. The container annotation is called MyRepeatedAnnos. The program accesses the repeated annotations by calling the getAnnotation() method, passing in the class of the container annotation, not the repeatable annotation itself. As the output shows, the repeated annotations are separated by a comma. They are not returned individually.

Another way to obtain the repeated annotations is to use one of the new methods added to the AnnotatedElement by JDK 8, which can operated directly on a repeated annotation. These are getAnnotationsByType() and getDeclaredAnnotationsByType(). Here, we will use the former. It is shown below :

<T extends Annotation> T[] getAnnotationsByType(Class<T> annoType)

It returns an array of annotations of annoType associated with the invoking object. If no annotations are present, the array will be zero length. Here is an example. Assuming the preceding example, the following sequence uses getAnnotationsByType() to obtain the repeated MyAnnotat annotations :

Annotation[] annos = m.getAnnotationsByType(MyAnnotat.class);
for(Annotation a : annos)
   System.out.println(a);

Here, the repeated annotation type, which is MyAnnotat, is passed to getAnnotationsByType(). The returned array contained all of the instances of MyAnnotat associated with myMethod(), which, in this example, is two. Each repeated annotation can be accessed via its index in the array. In this case, each MyAnnotat annotation is displayed via a for-each loop.

Some Restrictions

There are a number of restrictions that apply to the annotation declarations. First, no annotation can inherit another. Second, all the methods declared by an annotation must be without parameters. Furthermore, they must return one of the following :

Annotations can't be generic i.e. they can't take type parameters. Finally, annotation methods can't specify a throws clause.

Java Online Test


« Previous Tutorial Next Tutorial »