Какие типы могут использоваться для аннотаций 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
}