Почему интерфейсы не разрешены в качестве элементов аннотации?

Рассмотрим этот код:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Bar {
    Foo foo() default FooImpl.FooConstant;
}

Ошибка компилятора:

Значение аннотации не допустимого типа

Если я заменил Foo на FooImpl, код будет принят.

В чем причина такого поведения?

Ответ 1

Если я заменил Foo на FooImpl, код будет принят.

Я был бы очень удивлен, если бы это скомпилировано, если FooImpl не является перечислением.

Члены аннотации могут содержать только следующее:

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

Это ошибка времени компиляции, если возвращаемый тип метода, объявленного в тип аннотации - это любой тип, кроме одного из следующих: один из примитивные типы, String, Class и любой вызов класса, тип перечисления (§8.9), тип аннотации или массив (§10) одного из предшествующие типы. Это также ошибка времени компиляции, если какой-либо метод объявленный в типе аннотации, имеет подпись, которая переопределить эквивалент любого общедоступного или защищенного метода, объявленного в объекте класса или в аннотации интерфейса. Обозначение.

Источник: JLS

Ответ 2

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.7

Типы элементов аннотации должны быть следующими: примитивный, String, Class, Enum, массив любого из вышеперечисленных

Это ошибка времени компиляции, если тип элемента не соразмерен с ElementValue.

Надеюсь, это поможет!

Нашел то же самое в этой документации:

http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html

"Типы возвращаемых данных ограничены примитивами, строками, классами, перечислениями, аннотациями и массивами предыдущих типов". Как упоминалось, "интерфейс" не допускается.