Я думаю, это объясняется правилами определенного присваивания JLS для операторов switch
( JLS 16.2.9 ), в которых указано следующее:
"V[un] присваивается после оператора переключения, если все следующее верно:
- Либо в блоке коммутатора есть метка по умолчанию, либо V назначается [un] послевыражение переключения.
Если мы затем применим это к условному V
, которое является возвращаемым значением метода, мы можем видеть, что если default
нетветвь, значение было бы условно не назначено.
ОК ... Я экстраполирую определенные правила присваивания для покрытия возвращаемых значений, и, возможно, они не. Но тот факт, что я не смог найтичто-то более прямое в спецификации не означает, что его там нет: -)
Есть еще одна (более веская) причина, по которой компилятор должен выдавать ошибку.двоичные правила совместимости для enum
( JLS 13.4.26 ), которые устанавливаютследующее:
«Добавление или переупорядочение констант из типа enum не нарушит совместимость с уже существующими двоичными файлами.»
Так как же это сделатьприменять в этом случае?Хорошо предположим, что компилятору было позволено сделать вывод, что пример оператора switch OP всегда возвращал что-то.Что произойдет, если программист теперь изменит enum
, чтобы добавить дополнительную константу?Согласно правилам двоичной совместимости JLS, мы не нарушили двоичную совместимость.Тем не менее, метод, содержащий оператор switch
, теперь может (в зависимости от его аргумента) возвращать неопределенное значение.То, что не может быть допустимым, поэтому переключатель должен быть ошибкой компиляции.
В Java 12 были введены усовершенствования для коммутатора, включающие коммутаторвыражения.Это сталкивается с той же проблемой с перечислениями, которые изменяются между временем компиляции и временем выполнения.Согласно JEP 354 они решают эту проблему следующим образом:
Случаи выражения switch должны быть исчерпывающими;для всех возможных значений должна быть соответствующая метка переключателя.(Очевидно, что операторы switch не обязательно должны быть исчерпывающими.)
На практике это обычно означает, что требуется предложение по умолчанию;однако в случае выражения переключения перечисления, которое охватывает все известные константы, компилятор вставляет предложение по умолчанию, чтобы указать, что определение перечисления изменилось между временем компиляции и временем выполнения.Использование неявной вставки предложения по умолчанию делает код более надежным;теперь, когда код перекомпилирован, компилятор проверяет, что все случаи обрабатываются явно.Если бы разработчик вставил явное предложение по умолчанию (как в сегодняшнем случае), возможная ошибка была бы скрыта.
Единственное, что не совсем ясно, - это то, что фактически делает неявное предложение по умолчанию.Я предполагаю, что это приведет к непроверенному исключению.(На данный момент JLS для Java 12 не обновлялся для описания новых выражений переключателей.)