web-dev-qa-db-fra.com

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

Je pense que cela pourrait ne pas être possible dans Java car les annotations et leurs 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 j'aimerais savoir si je peux éviter de spécifier les chaînes dans chaque annotation que je préférerais utiliser.

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

Cependant, cela donne des erreurs de compilation comme la valeur d'annotation devrait être un initialiseur de tableau, etc. Est-ce que quelqu'un sait comment utiliser une constante String ou une constante String [] pour fournir une valeur à une annotation?

130
Kannan Ekanath

Constantes de compilation ne peuvent être que des primitives et des chaînes :

15.28. Expressions constantes

Une heure de compilation expression constante est une expression désignant une valeur de type primitif ou une chaîne qui ne se termine pas brutalement et qui est composée uniquement à l'aide des éléments suivants:

  • Littéraux de type primitif et littéraux de type String
  • Transmet vers des types primitifs et vers un type String
  • [...] les opérateurs [...]
  • Expressions entre parenthèses dont l'expression contenue est une expression constante.
  • Noms simples qui font référence à des variables constantes.
  • Noms qualifiés de la forme TypeName. Identifier qui font référence à des variables constantes.

En réalité, dans Java, il n’existe aucun moyen de protéger les éléments d’un tableau. Au moment de l’exécution, une personne peut toujours faire FieldValues.FIELD1[0]="value3" _, le tableau ne peut donc pas être vraiment constant si on regarde plus en profondeur.

115
irreputable

Vous pouvez utiliser une constante (c'est-à-dire une variable statique finale) comme paramètre pour une annotation. Par exemple, j’utilise quelque chose comme ceci assez souvent:

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 le TEST_TIMEOUT constante directement dans l'annotation.

De prime abord, je ne me souviens pas d’avoir essayé cela avec un tableau, vous pouvez donc rencontrer quelques problèmes avec 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 l’autre partie de votre question, vous pouvez certainement utiliser une chaîne constante sans aucun problème.

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

34
Andrzej Doyle

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

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

    public class Values {
        public static final String v1 = "A";
        public static final String v2 = "B";

        @SampleAnnotation(sampleValues = { v1, v2 })
        public void foo() {
        }
    }
10
Steve B.

Est-ce que quelqu'un sait comment utiliser une constante String ou une constante String [] pour fournir de la valeur à une annotation?

Malheureusement, vous ne pouvez pas faire cela avec des tableaux. Avec des variables autres que des tableaux, la valeur doit être statique finale.

7
Kevin

Je pense que cela pourrait ne pas être possible dans Java car les annotations et leurs paramètres sont> résolus au moment de la compilation).

Avec Seam 2 http://seamframework.org/ , vous avez été en mesure de résoudre les paramètres d'annotation au moment de l'exécution, avec un langage d'expression placé entre guillemets.

Dans Seam 3, cette fonctionnalité est le module Seam Solder http://seamframework.org/Seam3/Solder

5
jorgwel