【问题标题】:Java - Why is Enum<E> not allowed as Annotation member?Java - 为什么 Enum<E> 不允许作为注释成员?
【发布时间】:2016-01-22 09:49:20
【问题描述】:

上面写着:

原始

字符串

一个枚举

另一个注解

上述任何一个的数组

只有这些类型是合法的作为 Annotation 成员,为什么泛型 Enum 不能成为 Annotation 的成员?

例如:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {

    Enum value();

}

这是不允许的。但是枚举是一个常数不是吗?当您使用@Param(XXX) 时,填写Enum@Param(XXX) 被确定(这意味着这是恒定的)。为什么只允许特定的枚举成为成员?

我要做的是制作一个接收任何枚举的注释:

// for example
@Param(value = AEnum.ABC)
@Param(value = BEnum.TTT)
@Param(value = CEnum.OOO)

我希望以上所有内容都是合法的。

【问题讨论】:

  • 我认为是因为 Enum 和 Enum 是不同的类型。
  • 这只是语言设计,你不能。
  • @Jesper:这看起来不像是重复的。另一个问题是关于 Class 值,它恰好是 Class&lt;? extends Enum&gt;,但这只是巧合。另一个问题也适用于任何其他 Class&lt;? extends Foo&gt;,而这个问题是关于 enum instances 作为注释值。
  • @Holger 另一个问题(我问自己,顺便说一句)不仅仅是关于 Class 值,它通常是关于带有类型参数的注释属性,这与这里提出的问题相同。 (参数化类型是否为ClassEnum 或其他不相关)。显然答案是:这是不允许的,因为它会导致 Java 语言设计者不愿意承担的很多复杂性。
  • @Holger 好的,我明白了...我重新打开了它。还有一个问题可能有用:stackoverflow.com/questions/7594582/…

标签: java generics enums annotations


【解决方案1】:

虽然每个enum 类型都继承自java.lang.Enum,但Enum 类型本身并不是enum 类型。同样,虽然每个注解类型都继承自 java.lang.annotation.Annotation,但 Annotation 类型本身并不是注解类型。

这没有技术原因,在类文件中,每个实际值都将包含对其类型的引用。因此,将注释属性声明为Object 并动态发现实际值的类型在技术上是可行的,但正式规范不允许这样做。

顺便说一下,枚举常量也不是编译时常量。因此,虽然您可以声明像 final String FOO = "some string"; 这样的编译时常量并在像 @Name(value=FOO) 这样的注解中引用它,但您不能对 enum 常量做同样的事情。您只能引用enum 类型本身中声明的常量,如EnumType.NAME。这也是规范中正式定义的结果。

【讨论】:

    猜你喜欢
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多