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