Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why java annotation attributes have restrictions?

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?

like image 900
Adam Arold Avatar asked Sep 12 '13 17:09

Adam Arold


People also ask

What Cannot be annotated in Java?

Java scoping construct cannot be annotated with type-use.

Is @override annotation mandatory?

@Override @Override annotation informs the compiler that the element is meant to override an element declared in a superclass. Overriding methods will be discussed in Interfaces and Inheritance. While it is not required to use this annotation when overriding a method, it helps to prevent errors.

Why do we need custom annotations in Java?

☕️ Along with the plethora of predefined annotations that Java offers, we can define our custom annotations. Custom annotations help: Reduce the effort of writing code, by adding default behavior to methods. Add custom behavior to classes and interfaces.

What is the use of @interface annotation?

Annotation is defined like a ordinary Java interface, but with an '@' preceding the interface keyword (i.e., @interface ). You can declare methods inside an annotation definition (just like declaring abstract method inside an interface). These methods are called elements instead.


1 Answers

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.

like image 181
Sotirios Delimanolis Avatar answered Sep 30 '22 05:09

Sotirios Delimanolis