在Java中,为什么可以用另一个枚举常量限定枚举常量?

时间:2011-01-20 00:04:00

标签: java enums qualified-name

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

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

这是否有原因?

2 个答案:

答案 0 :(得分:10)

当您在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.SPRING; Season.WINTER将替换为其枚举类型Season

作为旁注,不鼓励从实例访问静态成员,因为它可能非常混乱。例如,如果您看到一段包含someThread.sleep()的代码,您可能会被误认为someThread已经入睡。但是,由于sleep()是静态的,因此该代码实际上正在调用Thread.sleep()来休眠当前线程。

答案 1 :(得分:1)

这是因为枚举是一种特殊的类。如果我们看看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.SPRING,因为它更简单,并且不太可能混淆读取代码的人。