【问题标题】:Why is enum not a constant expression?为什么枚举不是常量表达式?
【发布时间】:2018-03-26 09:39:20
【问题描述】:

下面是我正在试验的代码:

public enum PagesEnum {
    PAGE1 {
        public static final SectionsEnum SECTION_A = SectionsEnum.SECTION_A;
        public static final SectionsEnum SECTION_B = SectionsEnum.SECTION_B;
    },

    PAGE2 {
        public static final SectionsEnum SECTION_C = SectionsEnum.SECTION_C;
        public static final SectionsEnum SECTION_D = SectionsEnum.SECTION_D;
    }
}

public enum SectionsEnum {

    SECTION_A,
    SECTION_B,
    SECTION_C,
    SECTION_D
}

(实验的目标是得到类似PAGE1.SECTION_A的语法,但这不是本题的重点。)

我在 Eclipse 中收到以下编译器错误:

字段SECTION_A不能在非静态内部类型中声明为静态,除非用常量表达式初始化

现在我有点困惑。 SECTION_A 使用枚举 SectionsEnum.SECTION_A 初始化 - 为什么枚举不是常量表达式?我检查了 JLS,枚举确实没有在Constant Expressions 中收听。

我想知道,为什么会这样。

【问题讨论】:

  • PagesEnum 子类型由PAGE1{} 创建是静态的吗?也许这就是给你带来麻烦的部分:“......在非静态内部类型......”。
  • @MalteHartwig 我同意PAGE1{} 被视为“非静态内部类型”。但我不明白为什么枚举值不是“常量表达式”。从我的角度来看,Java 中没有什么比枚举值更稳定的了。
  • 是的,既然你这样重复......但无论如何,我认为它不会像你所想的那样工作:SECTION_X 将是@987654331 的匿名子类的常量@。因此,您永远无法访问它们,因为缺少作为前缀的类名。如果我删除了静态修饰符,Eclipse 会给我这个警告:“字段 new MyClass.PagesEnum(){}.SECTION_A 的值未使用”。那是定义常量的类...您无法访问,因为它是匿名的。
  • @watchme 好吧,“常量变量”实际上列在“常量表达式”中。
  • @MalteHartwig 你是对的,这个实验很可能会失败。我对此很好,但这不在我的问题范围内。

标签: java enums


【解决方案1】:

如果你想理解的话:那是因为Java 动态加载类并且enum 也是类。所以它应该在初始化的运行时解决。

如果要正式原因:JLS 15.28中的常量表达式定义

【讨论】:

  • 我知道正式的原因,我想知道为什么会这样。我想你是对的,一定与编译器如何处理常量表达式有关。
  • 对于 java 此变量的运行时类型是引用,您不能将值存储在 class 文件中,只能使用初始化它的代码。所以不是编译器,而是更多class文件格式问题。
猜你喜欢
  • 2019-06-11
  • 2013-05-02
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2022-10-08
相关资源
最近更新 更多