2010-01-14 20 views
106

Creo que esto puede no ser posible en Java porque la anotación y sus parámetros se resuelven en tiempo de compilación. Tengo una interfaz de la siguiente manera,Cómo proporcionar valor a una anotación desde un Java constante

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

y otra clase,

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

taco muchas clases con la anotación y me gustaría saber si puedo evitar especificar las cadenas en cada anotación I que preferirían que utilizar

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

Sin embargo, esto da errores de compilación como valor de anotación debe ser una matriz de inicialización, etc. ¿alguien sabe cómo puedo utilizar una cadena constante o String [] constante para proporcionar valor a una anotación?

Respuesta

92

Compilar constantes de can only be primitives and Strings:

15,28.Expresiones Constantes

A-tiempo de compilación expresión constante es una expresión que denota un valor de tipo primitivo o una cadena que no complete bruscamente y se compone utilizando sólo el siguiente:

  • literales de tipo primitivo y literales de tipo String
  • Los yesos de tipos primitivos y yesos para escribir String
  • operadores [...] [...]
  • Expresiones entre paréntesis cuya expresión contenida es una expresión constante.
  • Nombres simples que hacen referencia a variables constantes.
  • Nombres calificados del formulario TypeName. Identificador que se refieren a variables constantes.

En realidad, en java no hay manera de proteger los elementos de una matriz. En tiempo de ejecución, alguien siempre puede hacer FieldValues.FIELD1[0]="value3", por lo tanto, la matriz no puede ser realmente constante si miramos más profundamente.

+9

¡Enumera también! :) :) – TacB0sS

+2

Creo que la URL de referencia murió. Es la especificación de Java en constantes a lo que se refería? Es decir, http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 –

+0

@ TacB0sS, las enumeraciones no son expresiones constantes. – jaco0646

5

¿Alguien sabe cómo puedo utilizar una cadena constante o String [] constante para suministrar valor a una anotación?

Desafortunadamente, no se puede hacer esto con arreglos. Con variables que no son de matriz, el valor debe ser estático final.

32

Puede usar una constante (es decir, una variable final estática) como parámetro para una anotación. Como un ejemplo rápido, utilizo algo como esto con bastante frecuencia:

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); 
    } 
} 

Tenga en cuenta que es posible pasar la constante TEST_TIMEOUT directamente en la anotación.

Offhand, no recuerdo haber intentado esto con una matriz, por lo que puede tener algunos problemas con pequeñas diferencias en cómo las matrices se representan como parámetros de anotación en comparación con las variables de Java? Pero en cuanto a la otra parte de su pregunta, definitivamente podría usar una Cadena constante sin ningún problema.

EDIT: He acaba de intentar esto con una matriz de cadenas, y no encontrarse con el problema que usted ha mencionado - sin embargo, el compilador hicieron me dicen que el "valor del atributo debe ser constante" a pesar de la matriz se define como public static final String[]. Tal vez no le gusta el hecho de que las matrices son mutables? Hmm ...

+0

mala suerte para mí! Oh yah, pude pasar Cuerdas/Números pero no arreglos. Voy a pasar un poco más de tiempo en esto y si nada funciona aceptaré la respuesta :) –

+0

Sí, supongo que la mutabilidad de la matriz FIELD1 es el problema aquí. Se le permite declarar la matriz con un inicializador de matriz porque nada más puede tener acceso a esa matriz y, por lo tanto, no se puede cambiar más adelante. – ColinD

+0

Esto resuelve mi problema. Solo necesitaba compartir una constante de cadena entre anotaciones y código. ¡Gracias! – simon

9

No le está suministrando una matriz en su ejemplo. A continuación se compila 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() { 
     } 
    } 
+2

Se está suministrando una matriz en el ejemplo, pero no una que se crea directamente en la declaración de anotación. – ColinD

5

Estoy pensando que esto puede no ser posible en Java porque la anotación y sus parámetros> se resuelven en tiempo de compilación.

Con Seam 2 http://seamframework.org/ pudo resolver los parámetros de anotación en tiempo de ejecución, con el lenguaje de expresión entre comillas dobles.

En la costura 3 de esta función es el módulo de la costura de soldadura http://seamframework.org/Seam3/Solder

Cuestiones relacionadas