【问题标题】:In Java, why is it possible to qualify an Enum Constant with another Enum Constant?在 Java 中,为什么可以用另一个枚举常量来限定一个枚举常量?
【发布时间】:2011-01-20 00:04:00
【问题描述】:

最近,我注意到,有可能:

class Test {
    public enum Season { WINTER, SPRING, SUMMER, FALL }
    Season field = Season.WINTER.SPRING; // why is WINTER.SPRING possible?
}

这是有原因的吗?

【问题讨论】:

标签: java enums qualified-name


【解决方案1】:

当您在 Java 中访问对象(包括枚举)的静态成员时,编译器会有效地将对象替换为其静态类型。更具体地说,

class ExampleClass {
    static int staticField;
    static void staticMethod() {
        ExampleClass example = new ExampleClass();
        example.staticField;     // Equivalent to ExampleClass.staticField;
        example.staticMethod();  // Equivalent to ExampleClass.staticMethod();
    }
}

同样,由于枚举实际上是“静态的”,Season.WINTER.SPRING 等价于Season.SPRINGSeason.WINTER 被其枚举类型 Season 替换。

作为旁注,不鼓励从实例访问静态成员,因为它可能会造成混乱。例如,如果您看到一段包含someThread.sleep() 的代码,您可能会被欺骗相信someThread 已进入休眠状态。但是,由于sleep() 是静态的,因此该代码实际上是在调用使当前线程休眠的Thread.sleep()

【讨论】:

  • 我建议打开静态访问警告(Eclipse 有这个选项,其他 IDE 可能也有)。我总是出于这个特定原因修复这些警告:它们令人困惑,并且可能误导正在阅读代码的人认为程序正在做它没有做的事情。
【解决方案2】:

这是因为枚举是一种特殊的类。如果我们看一下 Season.WINTER 内部的字段,例如:

  for (Field field : Test.Season.WINTER.getClass().getFields())
   System.out.println(field);

我们将看到输出:

public static final TestEnum$Test$Season TestEnum$Test$Season.WINTER
public static final TestEnum$Test$Season TestEnum$Test$Season.SPRING
public static final TestEnum$Test$Season TestEnum$Test$Season.SUMMER
public static final TestEnum$Test$Season TestEnum$Test$Season.FALL

所以每个枚举值实际上也是枚举类Season 的静态常量,因此可以访问Season 的静态字段或其他枚举值(包括它自己)。

但是,直接从枚举中访问枚举值可能会更好,例如 Season.SPRING,因为它更简单且不太可能使阅读您的代码的人感到困惑。

【讨论】:

    猜你喜欢
    • 2015-08-21
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    相关资源
    最近更新 更多