如何从 Java 中的常量向注释提供枚举值 [英] How to supply Enum value to an annotation from a Constant in Java

查看:42
本文介绍了如何从 Java 中的常量向注释提供枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法使用从常量中提取的枚举作为注释中的参数.我收到此编译错误:注释属性 [attribute] 的值必须是枚举常量表达式".

I'm unable to use an Enum taken from a Constant as a parameter in an annotation. I get this compilation error: "The value for annotation attribute [attribute] must be an enum constant expression".

这是 Enum 代码的简化版本:

This is a simplified version of the code for the Enum:

public enum MyEnum {
    APPLE, ORANGE
}

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface MyAnnotation {
    String theString();

    int theInt();

    MyEnum theEnum();
}

还有班级:

public class Sample {
    public static final String STRING_CONSTANT = "hello";
    public static final int INT_CONSTANT = 1;
    public static final MyEnum MYENUM_CONSTANT = MyEnum.APPLE;

    @MyAnnotation(theEnum = MyEnum.APPLE, theInt = 1, theString = "hello")
    public void methodA() {

    }

    @MyAnnotation(theEnum = MYENUM_CONSTANT, theInt = INT_CONSTANT, theString = STRING_CONSTANT)
    public void methodB() {

    }

}

错误仅出现在方法 B 上的theEnum = MYENUM_CONSTANT"中.String 和 int 常量在编译器中是可以的,Enum 常量不是,即使它与方法 A 上的值完全相同.在我看来,这是编译器中缺少的功能,因为这三个显然都是常量.没有方法调用,没有奇怪的类使用等等.

The error shows up only in "theEnum = MYENUM_CONSTANT" over methodB. String and int constants are ok with the compiler, the Enum constant is not, even though it's the exact same value as the one over methodA. Looks to me like this is a missing feature in the compiler, because all three are obviously constants. There are no method calls, no strange use of classes, etc.

我想要实现的是:

  • 在注释中和后面的代码中使用 MYENUM_CONSTANT.
  • 保持输入安全.

实现这些目标的任何方式都可以.

Any way to achieve these goals would be fine.

谢谢大家.正如你所说,这是不可能的.JLS 应该更新.这次我决定忘记注释中的枚举,而使用常规的 int 常量.只要 int 是从命名常量分配的,值就会有界并且它是某种"类型安全的.

Thanks all. As you say, it cannot be done. The JLS should be updated. I decided to forget about enums in annotations this time, and use regular int constants. As long as the int is assigned from a named constant, the values are bounded and it's "sort of" type safe.

看起来像这样:

public interface MyEnumSimulation {
    public static final int APPLE = 0;
    public static final int ORANGE = 1;
}
...
public static final int MYENUMSIMUL_CONSTANT = MyEnumSimulation.APPLE;
...
@MyAnnotation(theEnumSimulation = MYENUMSIMUL_CONSTANT, theInt = INT_CONSTANT, theString = STRING_CONSTANT)
public void methodB() {
...

而且我可以在代码中的任何其他地方使用 MYENUMSIMUL_CONSTANT.

And I can use MYENUMSIMUL_CONSTANT anywhere else in the code.

推荐答案

好像是在JLS #9.7.1:

[...] V 的类型与 T 赋值兼容(第 5.2 节),此外:

[...] The type of V is assignment compatible (§5.2) with T, and furthermore:

  • [...]
  • 如果 T 是枚举类型,而 V 是枚举常量.

一个枚举常量被定义为实际的枚举常量(JLS #8.9.1),不是指向该常量的变量.

And an enum constant is defined as the actual enum constant (JLS #8.9.1), not a variable that points to that constant.

底线:如果您想使用枚举作为注释的参数,您需要给它一个明确的 MyEnum.XXXX 值.如果要使用变量,则需要选择另一种类型(不是枚举).

Bottom line: if you want to use an enum as a parameter for your annotation, you will need to give it an explicit MyEnum.XXXX value. If you want to use a variable, you will need to pick another type (not an enum).

一种可能的解决方法是使用 Stringint 然后您可以将其映射到您的枚举 - 您将失去类型安全性,但可以轻松发现错误运行时(= 测试期间).

One possible workaround is to use a String or int that you can then map to your enum - you will loose the type safety but the errors can be spotted easily at runtime (= during tests).

这篇关于如何从 Java 中的常量向注释提供枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆