268 votes

Quels types peuvent être utilisés pour les membres d'annotation Java ?

Aujourd'hui, je voulais créer ma première interface d'annotation suivante cette documentation et j'ai obtenu cette erreur de compilation

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

Évidemment Object ne peut pas être utilisé comme type d'un membre d'annotation. Malheureusement, je n'ai pas pu trouver d'informations sur les types qui peuvent être utilisés en général.

Je l'ai découvert par essais et erreurs :

  • String Valable
  • int Valable
  • Integer Invalide (de manière surprenante)
  • String[] Valable (de manière surprenante)
  • Object Invalide

Peut-être quelqu'un peut-il nous éclairer sur les types de produits qui sont effectivement autorisés et pourquoi.

0 votes

Il est possible que cela varie selon l'annotation - veuillez montrer le code que vous essayez d'écrire.

2 votes

Ajouté à la question. Mais je ne pense pas que ça varie.

354voto

skaffman Points 197885

Il est spécifié par section 9.6.1 de la JLS . Les types de membres de l'annotation doivent être l'un des suivants :

  • primitivo
  • Chaîne de caractères
  • un Enum
  • une autre annotation
  • Classe
  • un tableau de l'un des éléments ci-dessus

Cela semble restrictif, mais il y a sans doute des raisons à cela.

Notez également que les tableaux multidimensionnels (par ex. String[][] ) sont implicitement interdits par la règle ci-dessus.

Les tableaux de classes ne sont pas autorisés, comme décrit dans le document suivant cette réponse .

37 votes

Comment trouver ces pages/documents ? Je jure que je cherche sur Google chaque fois que je pose une question sur StackOverlow et sur de nombreuses questions Java, quelqu'un poste un lien vers la JSL qui répond à ma question. Pourquoi je ne trouve pas ces pages via Google !

11 votes

Le JLS n'est pas très adapté à Google. Vous devez juste savoir qu'il est là.

1 votes

Les mêmes informations sont également disponibles dans le guide d'annotation sur le site de sun (j'ai trouvé ça en googlant) : java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html

58voto

KLE Points 11711

Je suis d'accord avec Skaffman pour les types disponibles.

Restriction supplémentaire : il doit s'agir d'une constante de temps de compilation. .

Par exemple, les éléments suivants sont interdits :

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

36voto

fikovnik Points 1100

N'oubliez pas non plus que les annotations elles-mêmes peuvent faire partie d'une définition d'annotation . Cela permet une imbrication simple des annotations - pratique dans les cas où vous souhaitez qu'une annotation soit présente plusieurs fois.

Par exemple :

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

donde SimpleAnnotation es

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

y ComplexAnnotation est

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

Exemples tirés de : http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

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

6 votes

Avec Java 8 @Repeatable ce qui n'est plus nécessaire.

14voto

Josh Points 31

Le concept des annotations s'adapte très bien à la conception de mon projet, jusqu'à ce que je réalise qu'il n'est pas possible d'avoir des types de données complexes dans l'annotation. J'ai contourné ce problème en utilisant la classe de ce que je voulais instancier plutôt qu'un objet instancié de cette classe. Ce n'est pas parfait, mais Java l'est rarement.

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

0 votes

Quel type de cible avez-vous utilisé sur @interface Decorated ? J'ai essayé d'utiliser ce modèle dans mon projet, tout se compile mais à l'exécution j'obtiens un gros pointeur nul sur "String name" (dans mon cas : List<SomeStuff> myList (j'essaie de décorer un processeur générique avec une liste de choses qu'il doit faire pour traiter quelque chose).

1voto

Amos Kosgei Points 470

Selon Oracle, les types valides pour les éléments d'annotation sont les suivants :

1. Primitives (byte, char, int, long float, double)
2. Enums
3. Class (Think generics here Class <?>, Class<? extends/super T>>)
4. String
5. Array of the above (array[] of primitives, enums, String, or Class)
5. Another annotation.

Un plus à noter, tous les éléments sont par nature considérés comme publics et abstraits.

Par conséquent,

 static final variable(s) allowed as well.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X