Repeating
Annotations
Another new JDK 8 annotation
feature enables an annotation to be repeated on the same element. This is
called repeating annotations. For an
annotation to be repeatable, it must be annotated with the @Repeatable annotation, defined in 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.
To access the repeated
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 MyAnno shown previously into a
repeatable annotation and demonstrates its use.
// Demonstrate a repeated annotation.
import java.lang.annotation.*;
import java.lang.reflect.*;
Make MyAnno repeatable.
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnos.class) @interface MyAnno {
String str() default "Testing"; int
val() default 9000;
}
This is the container annotation.
@Retention(RetentionPolicy.RUNTIME) @interface
MyRepeatedAnnos {
MyAnno[] value();
}
class RepeatAnno {
// Repeat MyAnno on myMeth()
@MyAnno(str = "First annotation", val
= -1)
@MyAnno(str = "Second annotation",
val = 100)
public static void myMeth(String str, int i)
{
RepeatAnno ob = new RepeatAnno();
try {
Class<?> c = ob.getClass();
// Obtain the annotations for myMeth().
Method m = c.getMethod("myMeth",
String.class, int.class);
// Display the repeated MyAnno 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[]) {
myMeth("test", 10);
}
}
The output is shown here:
@MyRepeatedAnnos(value=[@MyAnno(str=First
annotation, val=-1), @MyAnno(str=Second annotation, val=100)])
As explained, in order for MyAnno to be repeatable, it must be
annotated with the @Repeatable annotation,
which specifies its container annotation. The container annotation is called MyRepeatedAnnos. The program accesses the repeated annotations by
calling getAnnotation( ), 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 AnnotatedElement by JDK 8, which can
operate directly on a repeated annotation. These are getAnnotationsByType( ) and getDeclaredAnnotationsByType(
). Here, we will use the former. It is shown here:
<T extends Annotation> T[ ]
getAnnotationsByType(Class<T> annoType)
It returns an array of the
annotations of annoType associated
with the invoking object. If no annotations are present, the array will be of
zero length. Here is an example. Assuming the preceding program, the following
sequence uses getAnnotationsByType( )
to obtain the repeated MyAnno
annotations:
Annotation[] annos =
m.getAnnotationsByType(MyAnno.class); for(Annotation a : annos)
System.out.println(a);
Here, the repeated annotation
type, which is MyAnno, is passed to getAnnotationsByType( ). The returned
array contains all of the instances of MyAnno
associated with myMeth( ), which, in
this example, is two. Each repeated annotation can be accessed via its index in
the array. In this case, each MyAnno
annotation is displayed via a for-each loop.
Some
Restrictions
There are a number of
restrictions that apply to annotation declarations. First, no annotation can
inherit another. Second, all methods declared by an annotation must be without
parameters. Furthermore, they must return one of the following:
A primitive type, such as int
or double
An object of type String
or Class
An enum type
Another annotation type
An array of one of the preceding types
Annotations cannot be
generic. In other words, they cannot take type parameters. (Generics are
described in Chapter 14.) Finally, annotation methods cannot specify a throws clause.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.