Почему я не могу получить постоянную ссылку 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:.