95 votes

Plusieurs annotations du même type sur un élément?

Je suis tenter de la gifler deux ou plusieurs annotations du même type sur un seul élément, dans ce cas, une méthode. Ici l'approximative de code que je travaille avec:

public class Dupe {
    public @interface Foo {
      String bar();
    }

    @Foo(bar="one")
    @Foo(bar="two")
    public void haha() {}
}

Lors de la compilation ci-dessus, javac se plaint d'une double annotation:

max@upsight:~/work/aube$ javac Dupe.java 
Dupe.java:5: double annotation

Est-il tout simplement pas possible de répéter les annotations de ce genre? Manière affectée de parler, ne sont pas les deux instances de @Foo ci-dessus différents, en raison de leur contenu différent?

Si ce qui précède n'est pas possible, quelles sont les solutions potentielles?

Mise à JOUR: j'ai été demandé de décrire mon cas d'utilisation. Va ici.

Je suis en train de construire une syntaxe sugarish mécanisme de "carte" Pojo du document dans les magasins comme MongoDB. Je veux permettre à des index spécifié que les annotations sur les getters ou organismes de normalisation. Voici un exemple artificiel:

public class Employee {
    private List<Project> projects;

    @Index(expr = "project.client_id")
    @Index(expr = "project.start_date")
    public List<Project> getProjects() { return projects; }
}

Évidemment, je veux être en mesure de trouver rapidement les instances de l'Employé par diverses propriétés de Projet. Je peux spécifier @Index à deux reprises avec différents expr() les valeurs, ou de prendre l'approche spécifié dans la accepté de répondre. Même si Hibernate fait cela, et il n'est pas considéré comme un hack, je pense qu'il a encore un sens pour au moins permettre d'avoir plusieurs annotations du même type sur un seul élément.

143voto

sfussenegger Points 16204

Deux annotations ou plus du même type ne sont pas autorisées. Cependant, vous pourriez faire quelque chose comme ça:

 public @interface Foos {
    Foo[] value();
}

@Foos({@Foo(bar="one"), @Foo(bar="two")})
public void haha() {}
 

Vous aurez cependant besoin d'une gestion dédiée de l'annotation Foos dans le code.

d'ailleurs, je viens d'utiliser cela il y a 2 heures pour contourner le même problème :)

68voto

mernst Points 448

En Java 8, il est possible d'écrire des annotations répétées / en double. Voir http://openjdk.java.net/jeps/120 .

À la fin du mois d'août 2012, la mise en œuvre figurait déjà dans OpenJDK (pour Java 8, qui ne sera pas encore officiellement publié): http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7151010 .

18voto

Sergei Pikalev Points 101

http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html

A partir de Java8, vous pouvez décrire des annotations répétables:

 @Repeatable(FooValues.class)
public @interface Foo {
    String bar();
}

public @interface FooValues {
    Foo[] value();
}
 

Remarque: value est un champ obligatoire pour la liste de valeurs.

Vous pouvez maintenant utiliser des annotations pour les répéter au lieu de remplir le tableau:

 @Foo(bar="one")
@Foo(bar="two")
public void haha() {}
 

12voto

KLE Points 11711

Comme dit par sfussenegger, ce n'est pas possible.

La solution habituelle est de construire un "multiple", annotation, qui gère un tableau de la précédente annotation. Il est généralement le même nom, avec un 's' suffixe.

Par ailleurs, c'est très utilisée dans de grands projets publics (Hibernate par exemple), donc il ne devrait pas être considéré comme un hack, mais plutôt une solution correcte pour ce besoin.


En fonction de vos besoins, il pourrait être préférable de permettre à votre annotation antérieure à gérer de multiples valeurs.

Exemple:

    public @interface Foo {
      String[] bars();
    }

3voto

mihahh Points 46

Si vous n'avez qu'un seul paramètre "bar", vous pouvez le nommer "valeur". Dans ce cas, il ne sera pas nécessaire d'écrire le nom du paramètre lorsque vous l'utiliserez comme ceci:

 @Foos({@Foo("one"), @Foo("two")})
public void haha() {}
 

un peu plus court et plus propre, à mon ..

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