Reputation: 51039
Java 8 allows multiple annotations of the same type on same element with the help of @Repeatable
annotation.
Unfortunately, they apparently forgot corresponding feature supporting for the case of one annotation:
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
public class MultipleAnnotationsCompatibility {
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface FileTypes {
FileType[] value();
}
@Inherited
@Repeatable(FileTypes.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface FileType {
String value();
}
@FileType("png")
@FileType("jpg")
public static class Image {
}
@FileType("xls")
public static class Worksheet {
}
public static void main(String[] args) {
FileTypes fileTypes;
fileTypes = Image.class.getAnnotation(FileTypes.class);
System.out.println("fileTypes for Image = " + Objects.toString(fileTypes));
fileTypes = Worksheet.class.getAnnotation(FileTypes.class);
System.out.println("fileTypes for Worksheet = " + Objects.toString(fileTypes));
}
}
The second println
outputs null
despite the fact, that there is no logical difference between the cases.
Is there any way to process the cases of 1 and 2+ annotations with the same code?
They should probably make boolean
parameter for @Repeatable
to treat singlecase annotations in the same way?
Upvotes: 2
Views: 205
Reputation: 328618
You can use Class::getAnnotationsByType
in both cases:
The difference between this method and
AnnotatedElement.getAnnotation(Class)
is that this method detects if its argument is a repeatable annotation type (JLS 9.6), and if so, attempts to find one or more annotations of that type by "looking through" a container annotation.
Revised example:
FileType[] fileTypes;
fileTypes = Image.class.getAnnotationsByType(FileType.class);
System.out.println("fileTypes for Image = " + Arrays.toString(fileTypes));
fileTypes = Worksheet.class.getAnnotationsByType(FileType.class);
System.out.println("fileTypes for Worksheet = " + Arrays.toString(fileTypes));
Outputs:
fileTypes for Image = [@abc$FileType(value=png), @abc$FileType(value=jpg)]
fileTypes for Worksheet = [@abc$FileType(value=xls)]
Upvotes: 5