Como fornecer valor para uma anotação de um java constante

Eu estou pensando que isso pode não ser possível em Java, porque a anotação e seus parâmetros são resolvidos em tempo de compilation. Eu tenho uma interface como segue,

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

e outra class como,

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

Marcar muitas classs com a anotação e gostaria de saber se posso evitar a especificação das cadeias em todas as annotations que preferiria usar

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

No entanto, isso fornece erros de compilation, como o valor da anotação deve ser um inicializador de matriz, etc. Alguém sabe como usar uma constante String ou String [] para fornecer valor a uma anotação?

As constantes de compilation podem ser apenas primitivas e strings :

15,28. Expressões Constantes

Uma expressão constante em tempo de compilation é uma expressão denotando um valor de tipo primitivo ou uma String que não é concluída abruptamente e é composta usando apenas o seguinte:

  • Literais do tipo primitivo e literais do tipo String
  • Casts para tipos primitivos e conversões para digitar String
  • […] operadores […]
  • Expressões parênteses cuja expressão contida é uma expressão constante.
  • Nomes simples que se referem a variables ​​constantes.
  • Nomes qualificados do formulário TypeName . Identificador que se refere a variables ​​constantes.

Na verdade, no java não há como proteger itens em um array. Em tempo de execução, alguém sempre pode fazer FieldValues.FIELD1[0]="value3" , portanto, a matriz não pode ser realmente constante se olharmos mais profundamente.

Você pode usar uma constante (ou seja, uma variável final estática) como parâmetro para uma anotação. Como um exemplo rápido, eu uso algo assim com bastante frequência:

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

Note que é possível passar a constante TEST_TIMEOUT diretamente para a anotação.

De improviso, não me lembro de ter tentado isso com uma matriz, então você pode estar se deparando com alguns problemas com pequenas diferenças em como as matrizes são representadas como parâmetros de anotação em comparação com as variables ​​Java? Mas quanto à outra parte da sua pergunta, você definitivamente poderia usar uma String constante sem problemas.

EDIT: Eu tentei isso com uma matriz de String e não executar o problema que você mencionou – no entanto o compilador disse-me que o “valor de atributo deve ser constante” apesar da matriz sendo definida como public static final String[] . Talvez não goste do fato de que as matrizes são mutáveis? Hmm…

Você não está fornecendo uma matriz em seu exemplo. O seguinte compila bem:

  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() { } } 

Alguém sabe como posso usar uma constante String ou String [] para fornecer valor a uma anotação?

Infelizmente, você não pode fazer isso com matrizes. Com variables ​​não matriciais, o valor deve ser estático final.

Eu estou pensando que isso pode não ser possível em Java porque a anotação e seus parâmetros são resolvidos em tempo de compilation.

Com o Seam 2 http://seamframework.org/, você conseguiu resolver os parâmetros de anotação em tempo de execução, com a linguagem de expressão entre aspas duplas.

No Seam 3 esse recurso é o módulo Seam Solder http://seamframework.org/Seam3/Solder