192 votes

Comment fournir une valeur à une annotation à partir d'une constante java

Je pense que cela n'est pas possible en Java, car l'annotation et ses paramètres sont résolus au moment de la compilation. J'ai une interface comme suit,

public interface FieldValues {
   String[] FIELD1 = new String[]{"value1", "value2"};
}

et une autre classe comme,

@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
   ....
}

Je marque de nombreuses classes avec l'annotation et je voudrais savoir si je peux éviter de spécifier les chaînes de caractères dans chaque annotation ; je préférerais plutôt utiliser

@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
   ....
}

Cependant, cela donne lieu à des erreurs de compilation, par exemple, la valeur de l'annotation devrait être un initialisateur de tableau, etc. Quelqu'un sait-il comment je peux utiliser une constante String ou String[] pour fournir une valeur à une annotation ?

159voto

irreputable Points 25577

Compiler les constantes ne peuvent être que des primitives et des chaînes de caractères :

15.28. Expressions constantes

Un temps de compilation expression constante est une expression désignant une valeur de type primitif ou une chaîne de caractères qui ne se termine pas brusquement et qui est composée en utilisant uniquement les éléments suivants :

  • Les littéraux de type primitif et les littéraux de type String
  • Les castings vers les types primitifs et les castings vers le type String
  • [...] opérateurs [...]
  • Les expressions entre parenthèses dont l'expression contenue est une expression constante.
  • Des noms simples qui font référence à des variables constantes.
  • Noms qualifiés de la forme Nom du type . Identifiant qui font référence à des variables constantes.

En fait, en Java, il n'y a aucun moyen de protéger les éléments d'un tableau. Au moment de l'exécution, quelqu'un peut toujours faire FieldValues.FIELD1[0]="value3" Par conséquent, le tableau ne peut pas être vraiment constant si nous regardons de plus près.

2 votes

@TacB0sS, les enums ne sont pas des expressions constantes.

1 votes

Eh bien... peut-être que vous devriez essayer et me faire savoir... Je les utilise tout le temps :)

8 votes

Une spécification plus pertinente se trouve sous Annotations . En plus d'une expression constante, une valeur d'annotation peut être une initialisateur de tableau , classe littérale o enum constant .

51voto

Andrzej Doyle Points 52541

Vous pouvez utiliser une constante (c'est-à-dire une variable statique et finale) comme paramètre d'une annotation. Pour donner un exemple rapide, j'utilise assez souvent quelque chose comme ceci :

import org.junit.Test;
import static org.junit.Assert.*;

public class MyTestClass
{
    private static final int TEST_TIMEOUT = 60000; // one minute per test

    @Test(timeout=TEST_TIMEOUT)
    public void testJDK()
    {
        assertTrue("Something is very wrong", Boolean.TRUE);
    }
}

Notez qu'il est possible de passer l'option TEST_TIMEOUT directement dans l'annotation.

Je ne me souviens pas d'avoir déjà essayé avec un tableau. Il se peut donc que vous rencontriez des problèmes liés à de légères différences dans la façon dont les tableaux sont représentés en tant que paramètres d'annotation par rapport aux variables Java. Mais pour ce qui est de l'autre partie de votre question, vous pouvez tout à fait utiliser une constante String sans aucun problème.

EDIT : Je viens d'essayer avec un tableau de String, et je n'ai pas rencontré le problème que vous avez mentionné - cependant le compilateur a fait me disent que la "valeur de l'attribut doit être constante" malgré le fait que le tableau soit défini en tant que public static final String[] . Peut-être n'aime-t-il pas le fait que les tableaux soient mutables ? Hmm...

1 votes

Pas de chance pour moi ! Oh oui, j'ai pu passer des chaînes de caractères et des nombres mais pas des tableaux. Je vais passer un peu plus de temps sur ce sujet et si rien ne fonctionne, j'accepterai la réponse :)

1 votes

Oui, je pense que la mutabilité du tableau FIELD1 est le problème ici. Vous êtes autorisé à déclarer le tableau avec un initialisateur de tableau car rien d'autre ne peut avoir accès à ce tableau et il ne peut donc pas être modifié ultérieurement.

1 votes

Cela résout mon problème. J'avais juste besoin de partager une constante String entre les annotations et le code. Merci !

14voto

Kevin Points 19613

Quelqu'un sait-il comment je peux utiliser un constante String ou constante String[] pour fournir une valeur à une annotation ?

Malheureusement, vous ne pouvez pas le faire avec des tableaux. Avec les variables qui ne sont pas des tableaux, la valeur doit être statique finale.

12voto

Steve B. Points 23227

Vous ne lui fournissez pas un tableau dans votre exemple. Ce qui suit compile bien :

public @interface SampleAnnotation {
    String[] sampleValues();
}

public class Values {
    public static final String val0 = "A";
    public static final String val1 = "B";

    @SampleAnnotation(sampleValues={ val0, val1 })
    public void foo() {
    }
}

4 votes

Un tableau lui est fourni dans l'exemple, mais pas un tableau créé directement dans la déclaration d'annotation.

5voto

jorgwel Points 53

Je pense que cela n'est pas possible en Java, car l'annotation et ses paramètres sont résolus au moment de la compilation.

Avec couture 2 http://seamframework.org/ vous avez pu résoudre les paramètres d'annotation au moment de l'exécution, avec le langage d'expression entre guillemets.

Dans la couture 3 http://seamframework.org/Seam3/Solder Cette fonction est le module Seam Solder.

3 votes

Non, tu n'as pas résolu les paramètres au moment de l'exécution. Les paramètres ont été résolus au moment de la compilation. Le fait qu'ils soient ensuite utilisés pour faire quelque chose au moment de l'exécution n'a littéralement rien à voir avec le moment où leurs valeurs ont été définies.

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