如何从一个常量的java提供一个注释的值

我想这可能是不可能在Java中,因为注释和它的参数在编译时解决。 我有一个界面如下,

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

和另一个类一样,

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

我用注释标记了许多类,我想知道是否可以避免在每个注释中指定string,而是倾向于使用

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

然而,这给编译错误像注释值应该是一个数组初始化等。有人知道我可以如何使用一个string常量或string[]常量为注释提供值?

编译常量只能是基元和string :

15.28。 常量expression式

编译时常量expression式是一个expression式,表示一个原始types的值或一个不会突然完成的string,并且仅由以下内容组成:

  • 原始types文字和Stringtypes的文字
  • 强制转换为原始types并强制转换为Stringtypes
  • 运营商[…]
  • 包含expression式的括号expression式是一个常量expression式。
  • 引用常量variables的简单名称。
  • 表单TypeName的合格名称。 引用常量variables的标识符

实际上,在java中,没有办法保护数组中的项目。 在运行时,总是可以做FieldValues.FIELD1[0]="value3" ,因此,如果我们看得更深,数组就不会是真正的常量。

您可以使用一个常量(即静态,最终variables)作为注释的参数。 作为一个简单的例子,我经常使用这样的东西:

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

请注意,可以将TEST_TIMEOUT常量直接传递给注释。

不好意思,我不记得曾经用数组来试过这个,所以你可能会遇到一些与Javavariables相比在数组表示方式上作为注释参数有些不同的问题? 但至于你的问题的其他部分,你可以肯定使用一个常量string没有任何问题。

编辑:我刚刚试过这个string数组,并没有遇到你提到的问题 – 但编译器告诉我,“属性值必须是常量”,尽pipe数组被定义为public static final String[] 。 也许它不喜欢数组是可变的事实? 嗯…

你没有在你的例子中提供一个数组。 以下编译罚款:

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

有人知道我怎么可以使用一个string常量或string[]常量为注释提供值?

不幸的是,你不能用数组来做到这一点。 对于非数组variables,该值必须是最终静态的。

我想这可能不可能在Java中,因为注释和它的参数在编译时被parsing。

使用Seam 2 http://seamframework.org/,您可以在运行时parsing注释参数,在双引号内使用expression式语言。;

在Seam 3中,此function是Seam Solder模块http://seamframework.org/Seam3/Solder