ChatGPT解决这个技术问题 Extra ChatGPT

Which types can be used for Java annotation members?

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 → Valid

int → Valid

Integer → Invalid (Surprisingly)

String[] → Valid (Surprisingly)

Object → Invalid

Perhaps someone can shed some light on which types are actually allowed and why.

possibly it varies by annotation - please show the code you're trying to write.
Added to the question. But I don't think it varies.

C
Community

It's specified by section 9.6.1 of the JLS. The annotation member types must be one of:

primitive

String

an Enum

another Annotation

Class

an array of any of the above

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.

Arrays of Class are not allowed as described in this answer.


How does one find those pages/documents? I swear I google everytime before asking on StackOverlow and on many Java question someone posts a link to the JSL which answers my question. Why do I not find those pages via Google?!
The JLS isn't very google-friendly. You just need to know that it's there.
the same information is also available in the annotation guide on sun's site (did find that googling): java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
Yes, I found that page, too, but I've must have missed that sentence, hidden in all that prose text. I've looked for something more table or list-like.
What's missing from the above list is "Annotation". You can have an annotation which contains another annotation or an array of another annotation.
L
Linh

I agree with Skaffman for the Types available.

Additional restriction : it has to be a compile-time constant.

For example, the following are forbidden:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())

o
oujesky

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)


With Java 8 @Repeatable, this is not needed anymore.
j
jdmichal

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
}

What target type did you use on @interface Decorated ? Tried to use this pattern in my project, everything compiles but at runtime i get a big fat null pointer on "String name" (in my case: List myList (trying to decorate a generic processor with a list of things it needs to do to process something)
A
Amos Kosgei

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.