2009-09-22 14 views
157

Dzisiaj chciałem utworzyć mojego pierwszego interfejsu adnotacji następujące this documentation i mam błąd kompilatora „Nieprawidłowy typ dla członka adnotacji”:Jakie typy mogą być używane dla członków adnotacji Java?

public @interface MyAnnotation { 
    Object myParameter; 
    ^^^^^^ 
} 

Oczywiście Object nie może być używany jako typ członek adnotacji. Niestety nie mogłem znaleźć żadnych informacji na temat tego, które typy mogą być używane w ogóle.

to znalazłem się za pomocą prób i błędów:

String --> Valid

int --> Valid

Integer --> Invalid (Surprisingly)

String[] --> Valid (Surprisingly)

Object --> Invalid

Może ktoś może rzucić nieco światła na jakie typy są rzeczywiście zabronione i dlaczego.

+0

możliwe różnice zależą od adnotacji - pokaż kod, który próbujesz napisać. – djna

+2

Dodano do pytania. Ale nie sądzę, że to się zmienia. –

Odpowiedz

226

Jest to określone przez section 9.6.1 of the JLS. Rodzaje użytkownika Adnotacja musi być:

  • pierwotnego
  • ciąg
  • klasy
  • wyliczenia
  • inny Adnotacja
  • tablicą któregokolwiek z powyższych

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

Należy również zauważyć, że wielowymiarowe macierze (na przykład String[][]) są domyślnie zabronione przez powyższą regułę.

+17

Jak znaleźć te strony/dokumenty? Przysięgam, że za każdym razem google, zanim zapytam o StackOverlow i na wiele pytań Java ktoś wysyła link do JSL, który odpowiada na moje pytanie. Dlaczego nie znajduję tych stron przez Google ?! –

+8

Usługa JLS nie jest przyjazna dla google. Musisz tylko wiedzieć, że tam jest. – skaffman

+1

te same informacje są również dostępne w przewodniku adnotacji na stronie słońca (znalazłem google): http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html – wds

53

Zgadzam się ze Skaffmanem na dostępne rodzaje.

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

Na przykład, następujące są zabronione:

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

Koncepcja adnotacji pasuje bardzo dobrze ze wzorem mojego projektu, aż zdałem sobie sprawę, że nie można mieć złożonych typów danych w adnotacji. Obejrzałem go, używając klasy tego, co chciałem utworzyć, a nie instancji przedmiotu tej klasy. Nie jest idealny, ale java rzadko jest.

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

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

Na przykład:

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

gdzie SimpleAnnotation jest

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

i ComplexAnnotation jest

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

Przykłady z: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

+3

W języku Java 8 '@ Repeatable', to już nie jest potrzebne. – Mordechai

Powiązane problemy