Reputation: 72534
Today I wanted to create my first annotation interface following this documentation and I got this compiler error
Invalid type for annotation member": public @interface MyAnnotation { Object myParameter; ^^^^^^ }
Obviously Object
cannot be used as type of an annotation member. Unfortunately I could not find any information on which types can be used in general.
This I found out using trial-and-error:
String
→ Validint
→ ValidInteger
→ Invalid (Surprisingly)String[]
→ Valid (Surprisingly)Object
→ InvalidPerhaps someone can shed some light on which types are actually allowed and why.
Upvotes: 308
Views: 141899
Reputation: 403581
It's specified by section 9.6.1 of the JLS. The annotation member types must be one of:
It does seem restrictive, but no doubt there are reasons for it.
Also note that multidimensional arrays (e.g. String[][]
) are implicitly forbidden by the above rule.
Upvotes: 407
Reputation: 947
According to Oracle the valid types for annotation elements are:
1. Primitives (byte, char, int, long float, double)
2. Enums
3. Class (Think generics here Class <?>, Class<? extends/super T>>)
4. String
5. Array of the above (array[] of primitives, enums, String, or Class)
5. Another annotation.
A plus to note, all elements are inherently considered public and abstract.
Therefore
static final variable(s) allowed as well.
Upvotes: 4
Reputation: 3603
Also don't forget that annotations themselves can be part of an annotation definition. This allows some simple annotation nesting - handy in cases where you would like to have one annotation present many times.
For example:
@ComplexAnnotation({
@SimpleAnnotation(a="...", b=3),
@SimpleAnnotation(a="...", b=3),
@SimpleAnnotation(a="...", b=3)
})
public Object foo() {...}
where SimpleAnnotation
is
@Target(ElementType.METHOD)
public @interface SimpleAnnotation {
public String a();
public int b();
)
and ComplexAnnotation
is
@Target(ElementType.METHOD)
public @interface ComplexAnnotation {
public SimpleAnnotation[] value() default {};
)
Examples taken from: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations
(original URL: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations)
Upvotes: 42
Reputation: 169
The concept of annotations fits really well with the design of my project, until I realized you can't have complex datatypes in the annotation. I got around it by using the class of what I wanted to instantiate rather than an instantiated object of that class. It's not perfect, but java rarely is.
@interface Decorated { Class<? extends PropertyDecorator> decorator() }
interface PropertyDecorator { String decorate(String value) }
class TitleCaseDecorator implements PropertyDecorator {
String decorate(String value)
}
class Person {
@Decorated(decorator = TitleCaseDecorator.class)
String name
}
Upvotes: 16