如何从常量 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 []常量为注释提供值吗?

227984 次浏览

有人知道我怎么用 字符串常量或字符串[]常量 为注释提供价值?

不幸的是,数组不能这样做。对于非数组变量,值必须是 final static。

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

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

编译常数 只能是原语和字符串:

15.28常数表达式

编译时 常数表达式是一个表达式,表示一个基元类型的值或一个不会突然完成的字符串,它只使用以下内容组成:

  • 基元类型的文字和 String类型的文字
  • 强制转换为基元类型,强制转换为 String类型
  • 操作员
  • 括号中的表达式,其包含的表达式是常量表达式。
  • 引用常量变量的简单名称。
  • 表单 类型名称.识别码中引用常量变量的限定名。

实际上在 java 中没有办法保护数组中的项。在运行时,总有人可以执行 FieldValues.FIELD1[0]="value3",因此如果我们更深入地研究,数组不可能是真正的常数。

我认为这在 Java 中是不可能的,因为注释及其参数是在编译时解析的。

使用 Seam 2 http://seamframework.org/,您能够在运行时解析注释参数,表达式语言使用双引号。

在 Seam 3 http://seamframework.org/Seam3/Solder中,这个功能是模块 Seam 焊接

可以在注释字段中使用枚举并引用该枚举