Почему следующее кодирует сбой для компиляции при изменении оператора выбора на
case ENUM1: doSomeStuff();
работы?
public enum EnumType
{
ENUM1, ENUM2, ENUM3;
void doSomeStuff()
{
switch(this)
{
case EnumType.ENUM1: doSomeStuff();
}
}
}
Это сделано для того, чтобы избежать возможности сравнения с разными типами перечислений. Имеет смысл ограничить его одним типом , то есть типом значения перечисления в операторе switch
.
Обновление : оно на самом деле для сохранения двоичной совместимости. Вот цитата из примерно половины главы 13.4.9 JLS:
Одна из причин, по которой требуется встраивание констант, состоит в том, что операторы
switch
требуют констант для каждогослучая
, и никакие два таких постоянных значения не могут быть одинаковыми. Компилятор проверяет повторяющиеся значения констант в оператореswitch
во время компиляции; формат файла классане выполняет символическую привязку значений регистра.
Другими словами, из-за идентификатора класса в EnumType.ENUM1
он не может быть представлен как выражение константы времени компиляции, хотя это требуется оператором switch
.
Это не совсем ответ на ваш вопрос, но если у вас есть код, зависящий от значения перечисления, вы также можете создать абстрактный метод в своем перечислении, который будет перегружен для каждое значение:
public enum EnumType {
ENUM1 {
@Override
public void doSomeStuff() {
// do something
}
},
ENUM2 {
@Override
public void doSomeStuff() {
// do something else
}
};
public abstract void doSomeStuff();
}
Поскольку вы переключаетесь на объект типа EnumType
и единственными возможными значениями для него являются константы перечисления, нет необходимости снова квалифицировать эти константы внутри переключателя. В конце концов, наличие в нем case OtherEnumType.ENUM1:
в любом случае было бы незаконным.