Reputation: 30538
I noticed that if I create an annotation:
public @interface NullableTypeOverride {
NullableType hibernateTypeOverride();
}
I have limited options for annotation attributes. The above code will not work because annotations only take primitive, String
or Class
types for their attributes.
So in this case I can't use this annotation like this:
@NullableTypeOverride(hibernateTypeOverride = Hibernate.INTEGER)
private Long distance;
My guess is that it has something to do with compile time vs. runtime but I'm not entirely sure. So what is the reason for this limitation and how can I work around it?
Upvotes: 7
Views: 1539
Reputation: 279990
The JLS states
It is a compile-time error if the return type of a method declared in an annotation type is not one of the following: a primitive type, String, Class, any parameterized invocation of Class, an enum type (§8.9), an annotation type, or an array type (§10) whose element type is one of the preceding types.
The reason for this is that annotations must have a constant value. If you provide a reference to an object that may change, you'll have problems. This is only relevant if the annotation's Retention is RUNTIME
.
public class Person {
public String name;
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
Person person();
}
@MyAnnotation(person = ???) // how to guarantee it won't change at runtime?
public void method1() {...}
What's that value supposed to be? And how can reflection libs cache it?
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
annotation.person(); // should be the same value every time
Remember, annotations are supposed to be metadata.
Upvotes: 7