Multiple annotations of the same type on one element?
Solution 1:
Note: This answer is partially outdated since Java 8 introduced the @Repeatable
annotation (see answer by @mernst). The need for a @Foos
container annotation and dedicated handling still remain though.
Two or more annotations of same type aren't allowed. However, you could do something like this:
public @interface Foos {
Foo[] value();
}
// pre Java 8
@Foos({@Foo(bar="one"), @Foo(bar="two")})
public void haha() {}
// post Java 8 with @Repeatable(Foos.class) on @Foo
@Foo(bar="one") @Foo(bar="two")
public void haha() {}
You'll need dedicated handling of Foos
annotation in code though.
Solution 2:
Repeating annotations in Java 8
In Java 8 (released in March 2014), it is possible to write repeated/duplicate annotations.
See tutorial, Repeating Annotations.
See specification, JEP 120: Repeating Annotations.
Solution 3:
Apart from the other ways mentioned, there is one more less verbose way in Java8:
@Target(ElementType.TYPE)
@Repeatable(FooContainer.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foo {
String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface FooContainer {
Foo[] value();
}
@Foo("1") @Foo("2") @Foo("3")
class Example{
}
Example by default gets, FooContainer
as an Annotation
Arrays.stream(Example.class.getDeclaredAnnotations()).forEach(System.out::println);
System.out.println(Example.class.getAnnotation(FooContainer.class));
Both the above print:
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
Solution 4:
http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
Starting from Java8 you can describe repeatable annotations:
@Repeatable(FooValues.class)
public @interface Foo {
String bar();
}
public @interface FooValues {
Foo[] value();
}
Note, value
is required field for values list.
Now you can use annotations repeating them instead of filling the array:
@Foo(bar="one")
@Foo(bar="two")
public void haha() {}