Quali tipi possono essere utilizzati per i membri delle annotazioni Java?


238

Oggi volevo creare la mia prima interfaccia di annotazione seguendo questa documentazione e ho riscontrato questo errore del compilatore

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

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

Questo l'ho scoperto usando tentativi ed errori:

  • String → Valido
  • int → Valido
  • Integer → Non valido (sorprendentemente)
  • String[] → Valido (sorprendentemente)
  • Object → Non valido

Forse qualcuno può far luce su quali tipi sono effettivamente ammessi e perché.


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

2
Aggiunto alla domanda. Ma non penso che vari.
Daniel Rikowski,

Risposte:


324

È specificato dalla sezione 9.6.1 del JLS . I tipi di membri di annotazione devono essere uno di:

  • primitivo
  • Corda
  • un Enum
  • un'altra annotazione
  • Classe
  • una matrice di uno dei precedenti

Sembra restrittivo, ma senza dubbio ci sono ragioni per questo.

Si noti inoltre che le matrici multidimensionali (ad esempio String[][]) sono implicitamente vietate dalla regola di cui sopra.

Le matrici di classe non sono consentite come descritto in questa risposta .


33
Come si trovano quelle pagine / documenti? Giuro di google ogni volta prima di fare una domanda su StackOverlow e su molte domande Java qualcuno pubblica un link alla JSL che risponde alla mia domanda. Perché non trovo quelle pagine tramite Google ?!
Daniel Rikowski il

10
JLS non è molto adatto a Google. Devi solo sapere che è lì.
Skaffman,

1
le stesse informazioni sono disponibili anche nella guida alle annotazioni sul sito di Sun (ho trovato quella su Google): java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
wds

1
Sì, ho trovato anche quella pagina, ma devo aver perso quella frase, nascosta in tutto quel testo in prosa. Ho cercato qualcosa di più simile a una tabella o a una lista.
Daniel Rikowski,

13
Ciò che manca dall'elenco sopra è "Annotazione". È possibile avere un'annotazione che contiene un'altra annotazione o una matrice di un'altra annotazione.
Matt,

58

Sono d'accordo con Skaffman per i tipi disponibili.

Limitazione aggiuntiva: deve essere una costante di compilazione-tempo .

Ad esempio, sono vietati:

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

31

Inoltre, non dimenticare che le annotazioni stesse possono far parte di una definizione di annotazione . Ciò consente un semplice annidamento delle annotazioni, utile nei casi in cui si desidera avere un'annotazione presente più volte.

Per 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();
)

ed ComplexAnnotationè

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

Esempi tratti da: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

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


6
Con Java 8 @Repeatable, questo non è più necessario.
Mordechai,

11

Il concetto di annotazioni si adatta molto bene al design del mio progetto, fino a quando ho capito che non è possibile inserire tipi di dati complessi nell'annotazione. Ci sono riuscito usando la classe di ciò che volevo istanziare piuttosto che un oggetto istanziato di quella classe. Non è perfetto, ma Java lo è raramente.

@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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.