Java: How to prevent non-top level annotations on type? e.g.,
@Target(value={ElementType.TYPE})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface FooList {
public Foo[] value();
}
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Foo {
public String name();
}
@FooList({
@Foo(name="ABC"),
@Foo(name="XyZ")
})
@Foo(name="EFG") // no compile error here
public class Bar {
}
@Foo should be inside @FooList only. But no compile error when @Foo is annotated on type Bar directly.
From the documentation of @Target
:
If an
@Target
meta-annotation is not present on an annotation interfaceT
, then an annotation of typeT
may be written as a modifier for any declaration.
And from §9.6.4.1 - Target of the Java Language Specification:
If an annotation of type
java.lang.annotation.Target
is not present on the declaration of an annotation interfaceA
, thenA
is applicable in all declaration contexts and in no type contexts.
From the documentation of @Target
:
This
@Target
meta-annotation indicates that the declared class or interface is intended solely for use as a member class or interface in complex annotation interface declarations. It cannot be used to annotate anything directly:@Target({}) public @interface MemberInterface { ... }
In short, meta-annotate your @Foo
annotation with @Target({})
.