[英]How to supply value to an annotation from a Constant java
我认为这在 Java 中可能是不可能的,因为注释及其参数是在编译时解析的。 我有一个界面如下,
public interface FieldValues {
String[] FIELD1 = new String[]{"value1", "value2"};
}
和另一个类,
@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
....
}
我用注释标记了许多类,我想知道是否可以避免在每个注释中指定字符串,而我更喜欢使用
@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
....
}
但是,这会导致编译错误,例如注释值应该是数组初始值设定项等。有人知道我如何使用 String 常量或 String[] 常量为注释提供值吗?
编译常量只能是原语和字符串:
15.28. 常量表达式
编译时常量表达式是表示原始类型值或不会突然完成并且仅使用以下内容组成的字符串的表达式:
- 原始类型的文字和
String
类型的文字- 转换为原始类型并转换为
String
类型- [...] 运营商 [...]
- 包含表达式是常量表达式的括号表达式。
- 引用常量变量的简单名称。
- 形式为TypeName 的限定名称。 引用常量变量的标识符。
实际上在java中没有办法保护数组中的项目。 在运行时,有人总是可以做FieldValues.FIELD1[0]="value3"
,因此如果我们深入研究,数组就不可能是真正的常量。
您可以使用常量(即静态的最终变量)作为注释的参数。 举个简单的例子,我经常使用这样的东西:
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
常量直接传递到注释中。
顺便说一句,我不记得曾经用数组尝试过这个,所以你可能会遇到一些问题,与 Java 变量相比,数组表示为注释参数的方式略有不同? 但是至于您问题的另一部分,您绝对可以毫无问题地使用常量 String。
编辑:我刚刚用 String 数组尝试过这个,并没有遇到你提到的问题 - 但是编译器确实告诉我“属性值必须是常量”,尽管数组被定义为public static final String[]
。 也许它不喜欢数组可变的事实? 唔...
在您的示例中,您没有为它提供数组。 以下编译正常:
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() {
}
}
有人知道如何使用 String 常量或 String[] 常量为注释提供值吗?
不幸的是,你不能用数组来做到这一点。 对于非数组变量,该值必须是最终静态的。
我认为这在 Java 中可能是不可能的,因为注释及其参数是在编译时解析的。
使用 Seam 2 http://seamframework.org/,您可以在运行时解析注释参数,在双引号内使用表达式语言。
在 Seam 3 http://seamframework.org/Seam3/Solder 中,此功能是模块 Seam Solder
您可以使用枚举并在注释字段中引用该枚举
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.