在Groovy中,有没有一种方法可以将常量传递给注解?

27
在Java中,可以将常量字符串作为参数传递给注解,但我不知道如何在Groovy中实现相同的效果。
例如:
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value=[ElementType.METHOD])
    public @interface MyGroovyAnnotation {
        String value()
    }

    class MyGroovyClass {

        public static final String VALUE = "Something"

        @MyGroovyAnnotation(value=VALUE)
        public String myMethod(String value) {
            return value    
        }
    }

在这里,如果我给方法myMethod加上注解@MyGroovyAnnotation,并传递一个字符串字面量,如@MyGroovyAnnotation(value="Something"),它可以完美地工作。但是,如果我像上面的示例一样尝试传递VALUE,就会出现以下错误:

来自Eclipse:

Groovy:Expected 'VALUE' to be an inline constant of type java.lang.String in @MyGroovyAnnotation

从GroovyConsole运行:

expected 'VALUE' to be an inline constant of type java.lang.String not a field expression in @MyGroovyAnnotation
 at line: 20, column: 31

Attribute 'value' should have type 'java.lang.String'; but found type 'java.lang.Object' in @MyGroovyAnnotation
 at line: -1, column: -1

有人知道我需要做什么才能让这个工作,或者它是否可能吗?感谢您提供任何帮助或洞察力。


可能是访问注释中的静态字段的重复问题。 - tim_yates
谢谢@tim_yates,我没有注意到那个问题。那里的问题类似,但所选择的答案并不是真正的解决方案,因为它没有任何区别。我会点赞提到Groovy bug链接的答案,但我还没有足够的声望来这样做。我会查看这个bug,看看是否可以为这个问题和那个旧问题提供更多信息。再次感谢! - grdryn
2个回答

34
我遇到了同样的问题,Gerard提供的答案可行,但我不需要创建一个新的Constants类,只需引用现有的类即可。
例如:
@Retention(RetentionPolicy.RUNTIME)
@Target(value=[ElementType.METHOD])
public @interface MyGroovyAnnotation {
    String value()
}

class MyGroovyClass {

    public static final String VALUE = "Something"

    @MyGroovyAnnotation(value=MyGroovyClass.VALUE)
    public String myMethod(String value) {
        return value    
    }
}

我想在被采纳的答案下留言,但是我没有50个声望值。


谢谢反馈,Jon。我认为这个比我原来的好。我已经将接受的答案改为这个......现在你有50分声望了! :) - grdryn
一年半后,现在Jon有1,130个声望值。增加了不少! - Eric Majerus

9
这里所提出的类似问题(accessing-static-field-in-annotation)与此不同,因为那里的答案是将String设置为final,而这里已经是这种情况了。我已经想到一种解决方法,所以我认为最好在这里回答以便于其他有相同疑问的人参考! :)
上面的代码不起作用,但指定传递给注释的字符串为另一个类中的字段却奇怪地可以正常工作:
    Retention(RetentionPolicy.RUNTIME)
    @Target(value=[ElementType.METHOD])
    public @interface MyGroovyAnnotation {
        String value()
    }

    class Constants {
        public static final String VALUE = "Something"
    }

    public class MyGroovyClass {

        @MyGroovyAnnotation(value=Constants.VALUE)
        public String myMethod(String value) {
            return value
        }
    }

我不确定为什么其中一种情况有效而另一种情况无效。阅读bug中提到的评论,似乎Groovy开发人员在处理将常量字符串引用作为注释参数传递时遇到了无法覆盖Java中所有情况的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接