Одним из преимуществ перечислений Java является то, что они по сути являются объектами, как и все остальные. В частности, вы можете иметь методы для констант и заставить свой enum реализовывать интерфейсы:
interface Useful {
void doStuff();
}
enum Foo implements Useful {
DEFAULT {
public void doStuff() {
...
}
},
MAGIC {
public void doStuff() {
...
}
}
}
Таким образом, вместо того, чтобы принимать аргументы типа enum, ваши методы могут принять любую реализацию интерфейса и, в частности, предоставить материал по умолчанию, если константы enum реализуют все необходимое.
Они также могут иметь членов:
enum Explicit {
FIRST(0), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
Обратите внимание, что константы имеют внутреннее числовое значение (отражающее положение константы среди ее пиров), которое доступно с использованием метода ordinal
:
assert Explicit.FIRST.ordinal() == 0;
Но полагаться на это немного опасно. Если вы собираетесь (скажем) сохранить константы перечисления в базе данных, то следующее изменение нарушит код:
enum Explicit {
FIRST(0), NEWELT(-1), SECOND(1), THIRD(2);
private final int value;
private Explicit(int v) {
this.value = v;
}
}
при использовании порядковых значений. По этой причине механизм сериализации использует имя константы вместо ее позиции при сериализации значений перечисления.
Итак:
Type.X + 1
будет
Enum.values()[Enum.X.ordinal() + 1]
и коммутатор может быть смоделирован с использованием интерфейсов, реализованных самим перечислением (вы можете использовать перечисления в выражениях переключателя в Java, но часто, заставляя перечисление реализовывать необходимый код, вы получите более поддерживаемый код)