我认为这在 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[] 常量为注释提供值吗?
编译常量 can only be primitives and Strings:
15.28。常量表达式 编译时常量表达式是表示原始类型值或字符串的表达式,它不会突然完成并且仅使用以下内容组成: 原始类型的文字和字符串类型的文字 转换为原始类型和转换为类型字符串 [...] 运算符 [...] 带括号的表达式,其包含的表达式是常量表达式。引用常量变量的简单名称。 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 数组尝试过这个,并没有遇到你提到的问题 - 但是编译器 did 告诉我“属性值必须是常量”,尽管数组是定义为 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
您可以使用枚举并在注释字段中引用该枚举
不定期副业成功案例分享
enum
,但它们不是编译时常量。当您编写static final EnumType VARIABLE = EnumType.ENUM_CONSTANT;
并尝试在注释中使用VARIABLE
时,差异会变得很明显;它行不通。您只能使用不是常量表达式的EnumType.ENUM_CONSTANT
,但在注释(和switch
语句)中特别允许使用。