如何从常量 java 向注释提供值

2022-08-31 06:46:39

我认为这在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[] 常量为注释提供值吗?


答案 1

编译常量只能是基元和字符串

15.28. 常量表达式

编译时常量表达式是表示基元类型值或 String 的表达式,它不会突然完成,并且仅使用以下内容组成:

  • 基元类型的文本和类型的文本String
  • 强制转换为基元类型,强制转换为类型String
  • [...]运算符 [...]
  • 带括号的表达式,其包含的表达式是常量表达式。
  • 引用常量变量的简单名称。
  • 格式为 TypeName 的限定名称。引用常量变量的标识符

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


答案 2

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

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 数组尝试了一下,并没有遇到你提到的问题 - 但是编译器确实告诉我,尽管数组被定义为 .也许它不喜欢数组是可变的这一事实?嗯。。。public static final String[]