Почему в Java можно квалифицировать константу Enum с другой константой Enum? - PullRequest
7 голосов
/ 20 января 2011

Недавно я заметил, что возможно иметь:

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

Есть ли причина для этого?

Ответы [ 2 ]

10 голосов
/ 20 января 2011

Когда вы обращаетесь к статическому члену объекта (включая перечисления) в 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 голос
/ 20 января 2011

Это потому, что перечисления - это особые классы.Если мы посмотрим на поля внутри 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

Таким образом, каждое значение перечисления на самом деле также является статическая константа класса enum, Season и т. Д. Имеют доступ к статическим полям Season или другим значениям enum (включая себя).

Однако, вероятно, лучше просто получить доступ к enumзначения непосредственно из перечисления, например Season.SPRING, поскольку это проще и с меньшей вероятностью запутает тех, кто читает ваш код.

...