Java 8 came with support for repeatable annotations through the use of "container" annotations:
@Repeatable(FooContainer.class)
@interface Foo {
String value();
}
@interface FooContainer {
Foo[] value();
}
@Foo("bar")
@Foo("baz")
public class SomeClass { }
I have a library where I want to support Java 7 (or newer). This library makes extensive use of annotations, and would greatly benefit from supporting repeatable annotations.
From what I understand, the container annotation works even in Java 7, only one would have to use this instead:
@FooContainer({@Foo("bar"),@Foo("baz")})
public class SomeClass { }
What I would ultimately like is: If the user of my library is using Java 8 the user will be able to use repeated annotation. If the user is using Java 7, he must stick to manually writing the container annotation.
Is something like this at all possible?
You need to provide two versions of your library:
Foo
with @Repeatable
.Foo
and FooContainer
.Unfortunately, you can't support both Java 7 and repeating annotations with one version of your library. If you want clients to be able to repeat the annotation, then Foo
must be meta-annotated as @Repeatable
. java.lang.annotation.Repeatable
is defined only in Java 8. Therefore, if annotation Foo
is meta-annotated as @Repeatable
, both Foo
and SomeClass
can only be compiled and run on JDK 8 and above. (It can only be run on JDK 8 because when SomeClass is loaded, then Foo will be loaded, and any meta-annotation on Foo will be loaded.)