Перечисляет с предложением броска по умолчанию? - PullRequest
0 голосов
/ 20 мая 2010

Я заметил следующее в спецификации языка Java в разделе перечислений здесь: ссылка

switch(this) {
  case PLUS:   return x + y;
  case MINUS:  return x - y;
  case TIMES:  return x * y;
  case DIVIDE: return x / y;
}
throw new AssertionError("Unknown op: " + this);

Однако, глядя на раздел определения оператора switch, я нигде не заметил этот конкретный синтаксис (связанный оператор throw).

Могу ли я использовать синтаксический сахар типа "регистр по умолчанию - выбрасывать исключение" вне определений перечисления? У него есть какое-то особое имя? Считается ли это хорошей / плохой практикой сокращать такое поведение «что-либо, отсутствующее в списке, вызывает исключение»?

Ответы [ 5 ]

3 голосов
/ 20 мая 2010

Позор создателю этого учебника за создание AssertionError - почему бы не использовать Исключения, которые Java уже предоставляет нам, например UnsupportedOperationException

2 голосов
/ 20 мая 2010

Я не уверен, что получу вас, но вы, похоже, считаете, что throw является частью синтаксиса switch в примере опубликованного кода. Это не относится к делу. Блок switch и оператор throw - это две разные вещи, которые в этом коде просто помещаются рядом друг с другом.

Более подробно: четыре case части в switch все содержат операторы return, что приводит к пропуску любых последующих инструкций в методе. Если ни одна из частей case не совпадает, выполнение продолжается на строке, следующей за блоком switch, который является throw.

Вы можете использовать throw после if очень похожим образом:

if (something) {
    return aValue;
}

throw new Exception("Nope");
0 голосов
/ 20 мая 2010

Как уже говорили другие, это не синтаксический сахар. Это работает, потому что все ветви на коммутаторе возвращаются из метода. Если какое-то другое значение перечисления было введено в коммутатор, оператор switch завершился бы без запуска какой-либо из ветвей, после чего выполнялся бы оператор throw.

switch(this) {
  case PLUS:   return x + y;
  case MINUS:  return x - y;
  case TIMES:  return x * y;
  case DIVIDE: return x / y;
  default: throw new AssertionError("Unknown op: " + this);
}

Этот код будет функционально эквивалентным. Основное различие между ними состоит в том, что ваш переключатель без условия по умолчанию создаст предупреждение компилятора, если значение добавлено в Enum, но не в оператор switch.

0 голосов
/ 20 мая 2010

В eclipse, если вы не охватите все значения перечисления в операторе switch, во время компиляции выдается предупреждение.

Если, однако, вы поставили default: чехол, предупреждение больше не работает. Так что, да, в некоторых IDE есть определенное преимущество: пропущен default случай, когда все значения перечисления включены в оператор switch.

В общем, если ваш оператор switch выходит за рамки 5-6 случаев, рассмотрите возможность изменения кода. Обычно люди не понимают, что перечисления в Java являются полноценными классами, а значения перечислений являются объектами первого класса, поэтому во многих случаях вместо управления поведением с помощью оператора switch вы можете попросить объект перечисления выполнить саму работу.

В этом конкретном примере перечисление может иметь метод doOp( int x, int y), и каждый член перечисления может реализовывать конкретную разновидность этого метода.

0 голосов
/ 20 мая 2010

Существует ключевое слово default:

switch (whatever) {
  // ...
  default: explode();
}

Если вы хотите, чтобы регистр по умолчанию генерировал исключение, тогда

  default: throw new Explode();

Ваш пример работает только так, как всеостальные ветви возвращаются из содержащей функции. На мой взгляд, это не очень хорошая привычка для кодирования.

...