Какие типы можно использовать для элементов аннотаций Java? - PullRequest
202 голосов
/ 22 сентября 2009

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

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

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

Это я выяснил, используя метод проб и ошибок:

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

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

Ответы [ 4 ]

281 голосов
/ 22 сентября 2009

Это определено разделом 9.6.1 JLS . Типы элементов аннотации должны быть одного из:

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

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

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

58 голосов
/ 22 сентября 2009

Я согласен со Скаффманом в отношении доступных типов.

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

Например, запрещено следующее:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())
23 голосов
/ 19 октября 2012

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

Например:

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

11 голосов
/ 07 сентября 2012

Концепция аннотаций очень хорошо вписывается в дизайн моего проекта, пока я не понял, что в аннотации не может быть сложных типов данных. Я справился с этим, используя класс того, что я хотел создать, а не объект этого класса. Это не идеально, но редко бывает 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...