Какие типы могут использоваться для аннотаций Java?

Сегодня я хотел создать свой первый интерфейс аннотации после этой документации, и я получил эту ошибку компилятора

Invalid type for annotation member":
public @interface MyAnnotation {
    Object myParameter;
    ^^^^^^
}

Очевидно, что Object нельзя использовать как тип элемента аннотации. К сожалению, я не смог найти никакой информации о том, какие типы могут быть использованы в целом.

Об этом я узнал методом проб и ошибок:

  • String → Действительный
  • int → Действительный
  • Integer → Неверно (Удивительно)
  • String[] → Действительный (Удивительно)
  • Object → Неверно

Возможно, кто-то может пролить свет на то, какие типы действительно разрешены и почему.

Ответ 1

Он указан раздел 9.6.1 JLS. Типы элементов аннотации должны быть следующими:

  • примитив
  • Строка
  • Класс
  • enum
  • другая аннотация
  • массив любого из вышеперечисленных

Это кажется ограничительным, но, несомненно, есть причины для этого.

Также обратите внимание, что многомерные массивы (например, String[][]) неявно запрещены указанным выше правилом.

Ответ 2

Я согласен с Skaffman в отношении доступных типов.

Дополнительное ограничение: оно должно быть константой времени компиляции.

Например, запрещено:

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

Ответ 3

Также не забывайте, что сами аннотации могут быть частью определения аннотации. Это позволяет несколько простых вложений аннотаций - удобно в тех случаях, когда вы хотите, чтобы одна аннотация присутствовала много раз.

Например:

@ComplexAnnotation({
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3)
})
public Object foo() {...}

где SimpleAnnotation это

@Target(ElementType.METHOD)
public @interface SimpleAnnotation {
    public String a();
    public int b();
)

и ComplexAnnotation является

@Target(ElementType.METHOD)
public @interface ComplexAnnotation {
    public SimpleAnnotation[] value() default {};
)

Примеры взяты из: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(оригинальный URL: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations)

Ответ 4

Концепция аннотаций очень хорошо соответствует дизайну моего проекта, пока я не понял, что вы не можете иметь сложные типы данных в аннотации. Я обошел его, используя класс того, что я хотел создать, а не экземпляр объекта этого класса. Это не идеально, но java редко бывает.

@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
}