如何从Constant java为注释提供值

Kan*_*ath 134 java arrays annotations

我认为这在Java中是不可能的,因为注释及其参数在编译时被解析.我有一个如下界面,

public interface FieldValues {
   String[] FIELD1 = new String[]{"value1", "value2"};
}
Run Code Online (Sandbox Code Playgroud)

和另一个班级,

@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
   ....
}
Run Code Online (Sandbox Code Playgroud)

我用注释标记了很多类,我想知道我是否可以避免在每个注释中指定字符串而我更愿意使用

@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
   ....
}
Run Code Online (Sandbox Code Playgroud)

但是这会产生编译错误,例如注释值应该是数组初始化器等.有人知道如何使用String常量或String []常量来为注释提供值吗?

irr*_*ble 121

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

15.28.常数表达式

编译时常量表达式是表示基本类型的值的表达式或不突然完成的字符串,仅使用以下内容组成:

  • 原始类型的文字和类型的文字 String
  • 转换为基本类型和转换为类型 String
  • [...]运营商[...]
  • 括号表达式,其包含的表达式是常量表达式.
  • 引用常量变量的简单名称.
  • TypeName表单的限定名称.引用常量变量的标识符.

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

  • 还有枚举!:) :) (12认同)
  • [注释](http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.7.1-300) 下有一个更相关的规范。除了常量表达式之外,注释值可以是 _array 初始值设定项_、_classliteral_ 或 _enum constant_。 (5认同)
  • @TacB0sS 您可以在注释中使用 `enum`,但它们不是编译时常量。当您编写 `static final EnumType VARIABLE = EnumType.ENUM_CONSTANT;` 并尝试在注释中使用 `VARIABLE` 时,差异变得明显;它不会工作。您只能使用不是常量表达式的`EnumType.ENUM_CONSTANT`,而是特别允许在注释(和`switch` 语句)中使用。 (3认同)
  • @TacB0sS,枚举不是常量表达式。 (2认同)

And*_*yle 34

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

另外,我不记得曾经用数组试过这个,所以你可能会遇到一些问题,与Java变量相比,数组如何表示为注释参数?但至于问题的其他部分,你绝对可以使用一个常量String而没有任何问题.

编辑:我刚刚尝试使用String数组,并没有遇到你提到的问题 - 但编译器确实告诉我"属性值必须是常量",尽管数组被定义为public static final String[].也许它不喜欢数组是可变的这个事实?嗯...


Ste*_* B. 10

在示例中,您没有为它提供数组.以下编译正常:

   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() {
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 它在示例中提供了一个数组,而不是直接在注释声明中创建的数组. (4认同)

Kev*_*vin 7

有人知道如何使用String常量或String []常量来为注释提供值吗?

不幸的是,你无法用数组做到这一点.对于非数组变量,该值必须是最终静态的.


小智 5

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

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

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

  • 不,您没有在运行时解析_the parameters_.该参数在编译时解析.然后他们习惯于在运行时做某事与他们的值设置时没有任何关系. (3认同)