为什么枚举不是常量表达式?

4
以下是我正在尝试的代码:
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,确实没有列出枚举作为常量表达式
我想知道这是为什么。

PagesEnum子类型由PAGE1{}静态创建吗?也许这就是让你困扰的部分:“……在非静态内部类型中……”。 - Malte Hartwig
@MalteHartwig 我认为PAGE1{}可以被视为“非静态内部类型”,这一点我没有问题。但是我不明白为什么枚举值不是“常量表达式”。在我看来,Java中很少有比枚举值更加常量的东西了。 - lexicore
是的,现在你这样重复一遍...但无论如何,我认为你的意图不会起作用:SECTION_X将是PagesEnum匿名子类的常量。因此,由于缺少类名来前缀它们,您永远无法访问它们。如果我删除静态修饰符,Eclipse会给我这个警告:“未使用字段new MyClass.PagesEnum(){}.SECTION_A的值”。那就是定义常量的类...由于它是匿名的,所以无法访问。 - Malte Hartwig
@watchme 嗯,“常量变量”实际上是列在“常量表达式”中的。 - lexicore
@MalteHartwig 您是正确的,这个实验很可能会失败。我可以接受这一点,但它不在我的问题范围内。 - lexicore
1个回答

2
如果您想理解原因:这是因为Java动态加载类,而enum也是一个类。因此,它应该在运行时进行解析以进行初始化。
如果您想要正式的原因:JLS 15.28中定义了常量表达式。

1
我知道正式的原因,但我想知道为什么会这样。我猜你是对的,可能与编译器如何处理常量表达式有关。 - lexicore
1
对于这个变量的java运行时类型是引用,你不能在class文件中存储值,只能存储初始化它的代码。因此,这不是编译器问题,而是更多的class文件格式问题。 - talex

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