Подтвердить что ты не робот

Константа перечисления содержит все константы перечисления одного и того же класса enum

Я просто понял, что константа enum в Java, похоже, содержит все константы перечисления того же типа.

Например, следующий код является законным:

enum State {
    enable, disable, deleted;
}

class Test {
    public static void main(String[] args) {
        for ( State s : State.enable.disable.values() ) {
            System.out.println(s);
         }
    }
}

Я был очень удивлен, когда увидел, что выход:

enable
disable
deleted

Не контр-интуитивно или даже нелогично, что константа enable содержит константу disable, которая в свою очередь содержит все константы enum State?

Какое возможное отношение к этому языковому дизайну?

4b9b3361

Ответ 1

Дизайнеры ошиблись, когда они впервые создали Java: статические члены, принадлежащие самому классу, а не к любому экземпляру класса, могут быть доступны с использованием экземпляра класса. рассмотрим этот класс:

class Foo {
    public static int bar = 0;
}

Обычно вы должны обращаться к переменной столбца, используя

int i = Foo.bar;

Но вы также можете сделать

Foo foo = new Foo();
int i = foo.bar;

Что здесь происходит. enable, disable, values(), являются статическими членами класса State, к которым следует обращаться с помощью State.enable, State.disable и State.values(). Но enable и disable также являются экземплярами класса State и поэтому могут также использоваться для доступа к статическим членам класса:

State state = State.enable;
State state2 = state.disable;

или проще:

State state2 = State.enable.disable;

Более того, вы могли бы сделать это без получения исключения NullPointerException:

State state = null;
State[] allStates = state.values();

Ответ 2

values() является статическим методом. Язык Java позволяет вам вызвать статический метод класса для любого экземпляра этого класса, но экземпляр игнорируется.

То же самое для enable, disable и deleted, которые являются статическими полями.

State.enable не содержит disable; скорее, State.enable.disable обрабатывается так же, как State.disable. И State.enable.disable.values() обрабатывается так же, как State.disable.values(), который обрабатывается так же, как State.values(), который, конечно, возвращает массив из всех трех значений.

Ответ 3

.values() - это неявный static метод на enum, и независимо от того, какое значение вы вызываете, вы получите тот же результат, что и State.values().

В то же время вы вызываете статический метод для экземпляра (вместо этого напрямую ссылаетесь на имя класса).

На самом деле, вызывая методы static для экземпляров, следует поднять предупреждение, в котором намекает, что вы делаете неправильно.