2009-09-22 13 views
157

Oggi ho voluto creare il mio primo interfaccia annotazione seguente this documentation ed ho ottenuto l'errore del compilatore "tipo non valido per il membro annotazione":Quali tipi possono essere utilizzati per i membri di annotazione Java?

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

Ovviamente Object non può essere utilizzato come tipo di un membro di annotazione. Purtroppo non sono riuscito a trovare alcuna informazione su quali tipi possono essere usati in generale.

Questo ho scoperto utilizzando trial-and-error:

String --> Valid

int --> Valid

Integer --> Invalid (Surprisingly)

String[] --> Valid (Surprisingly)

Object --> Invalid

Forse qualcuno può far luce su quali tipi sono in realtà ammessi e perché.

+0

forse varia in base all'annotazione: mostra il codice che stai cercando di scrivere. – djna

+2

Aggiunto alla domanda. Ma non penso che vari. –

risposta

226

È specificato da section 9.6.1 of the JLS. I tipi di utente annotazioni devono essere:

  • primitiva
  • String
  • Classe
  • un Enum
  • un'altra nota
  • una matrice di una delle suddette

Sembra restrittivo, ma senza dubbio ci sono dei motivi.

Si noti inoltre che gli array multidimensionali (ad esempio String[][]) sono implicitamente vietati dalla regola precedente.

+17

Come si trovano quelle pagine/documenti? Giuro sempre su google prima di chiedere su StackOverlow e su molte domande Java qualcuno pubblica un link alla JSL che risponde alla mia domanda. Perché non trovo queste pagine tramite Google ?! –

+8

Il JLS non è molto adatto per Google. Hai solo bisogno di sapere che è lì. – skaffman

+1

le stesse informazioni sono anche disponibili nella guida di annotazione sul sito di Sun (trovato che googling): http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html – wds

53

Sono d'accordo con Skaffman per i Tipi disponibili.

Restrizione aggiuntiva: deve essere una costante in fase di compilazione.

Ad esempio, è proibito il seguente:

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

Il concetto di annotazioni si adatta molto bene con il design del mio progetto, fino a quando ho capito che non si può avere tipi di dati complessi in annotazione. Mi sono aggirato usando la classe di ciò che volevo istanziare piuttosto che un oggetto istanziato di quella classe. Non è perfetto, ma raramente lo 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 
} 
15

Inoltre, non dimenticare che le annotazioni stessi possono essere parte di una definizione di annotazione. Ciò consente un semplice annidamento delle annotazioni, utile nei casi in cui desideri presentare più volte un'annotazione.

Ad esempio:

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

dove SimpleAnnotation è

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

e ComplexAnnotation è

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

Esempi tratti da: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

+3

Con Java 8 '@ ripetibile', questo non è più necessario. – Mordechai

Problemi correlati