2009-09-22 10 views
157

Heute wollte ich meine erste Anmerkung Schnittstelle erstellen this documentation folgenden und ich bekam den Compiler-Fehler „Ungültiger Typen für Annotation Mitglied“:Welche Typen können für Java-Annotations-Member verwendet werden?

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

Offensichtlich Object nicht als Typ einer Annotation Element verwendet werden kann. Leider konnte ich keine Informationen darüber finden, welche Typen allgemein verwendet werden können.

Das fand ich mit Trial-and-Error-out:

String --> Valid

int --> Valid

Integer --> Invalid (Surprisingly)

String[] --> Valid (Surprisingly)

Object --> Invalid

Vielleicht kann jemand etwas Licht auf, welche Arten tatsächlich erlaubt sind und warum.

+0

möglicherweise variiert es durch Anmerkung - zeigen Sie bitte den Code, den Sie versuchen zu schreiben. – djna

+2

Zu der Frage hinzugefügt. Aber ich denke nicht, dass es variiert. –

Antwort

226

Es wird durch section 9.6.1 of the JLS spezifiziert.

  • primitiv
  • String
  • Klasse
  • ein ENUM
  • ein andere Annotation
  • ein Array von einem der oben genannten

: Die Anmerkung Elementtypen einer der folgenden sein müssen Es scheint restriktiv, aber zweifellos gibt es Gründe dafür.

Beachten Sie auch, dass mehrdimensionale Arrays (z. B. String[][]) implizit durch die obige Regel verboten sind.

+17

Wie findet man diese Seiten/Dokumente? Ich schwöre, ich google jedes Mal, bevor ich auf StackOverlow frage und auf vielen Java-Fragen jemand einen Link zum JSL postet, der meine Frage beantwortet. Warum finde ich diese Seiten nicht über Google ?! –

+8

Die JLS ist nicht sehr Google-freundlich. Sie müssen nur wissen, dass es da ist. – skaffman

+1

die gleichen Informationen sind auch in der Annotation Guide auf der Website der Sonne (hat das googeln gefunden): http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html – wds

53

Ich stimme Skaffman für die verfügbaren Typen zu.

Zusätzliche Einschränkung: Es muss eine Kompilierzeitkonstante sein.

Zum Beispiel sind die folgenden verboten:

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

Das Konzept der Annotationen mit dem Design von meinem Projekt wirklich gut passt, bis ich erkannte Sie nicht komplexe Datentypen in der Anmerkung haben. Ich habe es geschafft, indem ich die Klasse von dem, was ich instanziieren wollte, anstelle eines instantiierten Objekts dieser Klasse verwendete. Es ist nicht perfekt, aber Java ist selten.

@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

Vergessen Sie auch nicht, dass Annotationen können sich Teil einer Anmerkung Definition sein. Dies ermöglicht eine einfache Annotationsverschachtelung - praktisch in Fällen, in denen Sie gerne mehrere Annotationen haben möchten.

Zum Beispiel:

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

wo SimpleAnnotation ist

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

und ComplexAnnotation ist

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

Beispiele entnommen aus: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

+3

Mit Java 8 '@ Repeatable' wird dies nicht mehr benötigt. – Mordechai

Verwandte Themen