Константа перечисления содержит все константы перечисления одного и того же класса 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
?
Какое возможное отношение к этому языковому дизайну?
Ответы
Ответ 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
для экземпляров, следует поднять предупреждение, в котором намекает, что вы делаете неправильно.