web-dev-qa-db-fra.com

Quels types peuvent être utilisés pour Java?

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

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

De toute évidence, Object ne peut pas être utilisé comme type de membre d'annotation. Malheureusement, je n'ai trouvé aucune information sur les types pouvant être utilisés en général.

J'ai découvert cela par essais et erreurs:

  • String → valide
  • int → valide
  • Integer → invalide (étonnamment)
  • String[] → Valable (étonnamment)
  • Object → invalide

Peut-être que quelqu'un peut nous éclairer sur quels types sont réellement autorisés et pourquoi.

207
Daniel Rikowski

C'est spécifié par section 9.6.1 du JLS . Les types de membre d'annotation doivent être l'un des suivants:

  • primitif
  • Chaîne
  • Classe
  • un enum
  • une autre annotation
  • un tableau de ce qui précède

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

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

291
skaffman

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

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

Par exemple, les actions suivantes sont interdites:

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

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 souhaiteriez avoir une annotation présente plusieurs fois.

Par exemple:

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

SimpleAnnotation est

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

et 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 d'origine: https://blogs.Oracle.com/toddfast/entry/creating_nested_complex_Java_annotations )

24
fikovnik

Le concept des annotations correspond parfaitement à la conception de mon projet, jusqu'à ce que je réalise que vous ne pouvez pas avoir de types de données complexes dans l'annotation. Je l'ai contourné 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
}
11
Josh