Jakie typy mogą być używane dla członków adnotacji Java?


238

Dzisiaj chciałem utworzyć swój pierwszy interfejs adnotacji zgodnie z tą dokumentacją i dostałem ten błąd kompilatora

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

Oczywiście Objectnie można go użyć jako typu elementu adnotacji. Niestety nie mogłem znaleźć żadnych informacji na temat tego, które typy można ogólnie zastosować.

Przekonałem się o tym metodą prób i błędów:

  • String → Ważne
  • int → Ważne
  • Integer → Nieprawidłowy (zaskakująco)
  • String[] → Ważne (zaskakująco)
  • Object → Nieprawidłowy

Być może ktoś może rzucić nieco światła na to, które typy są dozwolone i dlaczego.


być może zależy to od adnotacji - pokaż kod, który próbujesz napisać.
— djna

2
Dodano do pytania. Ale nie sądzę, że to się zmienia.
— Daniel Rikowski

Odpowiedzi:


324

Jest to określone w sekcji 9.6.1 JLS . Typy elementów adnotacji muszą być jednym z:

  • prymitywny
  • Strunowy
  • Enum
  • kolejna adnotacja
  • Klasa
  • tablica dowolnego z powyższych

Wydaje się to restrykcyjne, ale bez wątpienia istnieją ku temu powody.

Należy również pamiętać, że tablice wielowymiarowe (np. String[][]) Są domyślnie zakazane przez powyższą zasadę.

Tablice klasy nie są dozwolone, jak opisano w tej odpowiedzi .


33
Jak znaleźć te strony / dokumenty? Przysięgam, że google za każdym razem, zanim zadam pytanie na StackOverlow i na wiele pytań Java ktoś zamieszcza link do JSL, który odpowiada na moje pytanie. Dlaczego nie mogę znaleźć tych stron za pośrednictwem Google ?!
— Daniel Rikowski

10
JLS nie jest zbyt przyjazny dla Google. Musisz tylko wiedzieć, że tam jest.
— skaffman

1
te same informacje są również dostępne w przewodniku adnotacji na stronie firmy Sun (znalazłem to googling): java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
— wds

1
Tak, też znalazłem tę stronę, ale musiałem przeoczyć to zdanie, ukryte w całym tekście prozy. Szukałem czegoś bardziej podobnego do tabeli lub listy.
— Daniel Rikowski

13
Na powyższej liście brakuje „Adnotacji”. Możesz mieć adnotację, która zawiera inną adnotację lub tablicę innej adnotacji.
— Matt

58

Zgadzam się z Skaffmanem na dostępne typy.

Dodatkowe ograniczenie: musi to być stała czasowa kompilacji .

Na przykład zabronione są:

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

31

Nie zapominaj również, że same adnotacje mogą być częścią definicji adnotacji . Umożliwia to proste zagnieżdżanie adnotacji - przydatne w przypadkach, w których chciałbyś mieć jedną adnotację wiele razy.

Na przykład:

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

gdzie SimpleAnnotationjest

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

i ComplexAnnotationjest

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

Przykłady zaczerpnięte z: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(oryginalny adres URL: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations )


6
W Javie 8 @Repeatablenie jest to już potrzebne.
— Mordechai

11

Pojęcie adnotacji bardzo dobrze pasuje do projektu mojego projektu, dopóki nie zdałem sobie sprawy, że w adnotacji nie można mieć złożonych typów danych. Obejrzałem to, używając klasy tego, co chciałem utworzyć, a nie obiektu tej klasy. To nie jest idealne, ale java rzadko.

@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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.