代码之家  ›  专栏  ›  技术社区  ›  Kannan Ekanath

如何从常数Java向注释提供值

  •  119
  • Kannan Ekanath  · 技术社区  · 15 年前

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

    public interface FieldValues {
       String[] FIELD1 = new String[]{"value1", "value2"};
    }
    

    另一类是,

    @SomeAnnotation(locations = {"value1", "value2"})
    public class MyClass {
       ....
    }
    

    我用注释标记许多类,我想知道是否可以避免在每个注释中指定字符串

    @SomeAnnotation(locations = FieldValues.FIELD1)
    public class MyClass {
       ....
    }
    

    但是,这会导致编译错误,如注释值应为数组初始值设定项等。是否有人知道如何使用字符串常量或字符串[]常量为注释提供值?

    5 回复  |  直到 8 年前
        1
  •  108
  •   Arjan    10 年前

    编译常量 can only be primitives and Strings :

    15.28。常量表达式

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

    • 原始类型的文字和类型的文字 String
    • 强制转换为基元类型和强制转换为类型
    • […]运算符[…]
    • 包含表达式为常量表达式的带括号表达式。
    • 引用常量变量的简单名称。
    • 窗体的限定名 类型名 . 标识符 指的是常量变量。

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

        2
  •  33
  •   Andrzej Doyle    15 年前

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

    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 常量直接进入注释。

    顺便说一下,我不记得曾经用数组来测试过这个问题,所以你可能会遇到一些问题,这些数组和注释变量相比,数组是如何表示的?但是对于问题的另一部分,您可以毫无问题地使用常量字符串。

    编辑:我刚用一个字符串数组尝试过这个方法,没有遇到你提到的问题——但是编译器 告诉我“属性值必须是常量”,尽管数组被定义为 public static final String[] . 也许它不喜欢数组是可变的这一事实?隐马尔可夫模型。。。

        3
  •  10
  •   Steve B.    15 年前

    您的示例中没有为它提供数组。以下内容很好:

       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() {
            }
        }
    
        4
  •  6
  •   Kevin    15 年前

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

    不幸的是,不能对数组执行此操作。对于非数组变量,该值必须是最终的静态值。

        5
  •  5
  •   jorgwel    13 年前

    我认为这在Java中是不可能的,因为注释和它的参数在编译时被解决了。

    带缝2 http://seamframework.org/ 您可以在运行时解析注释参数,表达式语言位于双引号内。

    在Seam 3中,这一特性是模块接缝焊料 http://seamframework.org/Seam3/Solder