2013-07-21 2 views
2

Рассмотрим следующий кодПонимание поведения переключателя

int x = 1 
switch(x) { 
    case 1: 
     System.out.println("1"); 
    case 2: 
     System.out.println("2"); 
    default: 
     System.out.println("no value found"); 
} 

печатает

1 
2 
no value found 

, как и ожидалось, потому что не в каждом случае заявление не break
мои сомнения в том, что, как исполнение идет в каждом случае заявление если нет первого перерыва
, потому что x не равно 2, то и его исполнение case 2 блок
, но я понял default один, потому что без break программа продолжит выполнение и выполнить default statement

ответ

2

Это остаток языка программирования C. В C switch это немного больше, чем немного синтаксического сахара над goto в зависимости от значения выражения, и, таким образом, выполнение просто переходит к соответствующему case и продолжается оттуда. Метки между ними точно такие: метки.Они являются точками перехода, но не влияют на поток управления в противном случае, и с точки зрения компилятора нет ничего в ярлыке, который заслуживает скачка в другом месте (кроме там, где есть INTERCAL COMEFROM). Поэтому вы должны указать явное break после каждого случая, когда вы не хотите перейти к другим параметрам.

Java более или менее унаследовал эти семантики, избегая некоторых of the crazier C idioms.

C# с другой стороны идет немного дальше, запрещая провал полностью на непустых ярлыках case.

По-моему, это была небольшая ошибка дизайна. Провал по умолчанию может быть намного проще реализовать в компиляторе (потому что вам не нужно добавлять goto в конец switch, и он очень хорошо сочетается с тем, как все работает на самом деле), но по моему опыту значительно больше ошибок программирования, случайно используя провал, чем случайно не, используя его.

Самая серьезная ошибка дизайна в моих глазах включает в себя заявление switch со всей его странностью на современных языках.

0

По причинам, которые унаследовали от C++, выполнение, естественно, не происходит до конца переключателя или перерыва. Нет никакого теста против случаев, когда они встречаются.

0

switch Проваливается. Вам нужно добавить break перед каждым следующим case, если вы этого не хотите.

switch (x) { 
    case 1: 
     System.out.println("1"); 
     break; 
    case 2: 
     System.out.println("2"); 
     break; 
    default: 
     System.out.println("no value found"); 
} 
0

Переключатель утверждение является абстракцией branch table и таблицу филиал также имеет неявный падение-через и требует дополнительной инструкции перехода, чтобы избежать этого. Прочтите это и SO answer.

В соответствии с JLS 14.11:

Тело переключателя заявление известен как переключатель блока.

Если одна из констант случая равна значению выражения, то мы говорим, что случай соответствует, и все инструкции после метки соответствия в блоке коммутатора , если они есть, выполняются последовательно.

Если все эти утверждения завершены нормально или если нет инструкций после метки соответствия, то вся инструкция switch завершается нормально.

0

Это связано с тем, как он скомпилирован и оптимизирован.

Именно поэтому переключатель предпочтительнее связки прикованных операторов if.

0

От java doc:

Высказывание перерыва необходим, потому что без них, заявления в переключателях блоков провалиться: Все заявления после согласования случае метки выполняется в последовательности, независимо от выражения последующих наклейки с ярлыками, до тех пор, пока не будет встречен оператор break

0

Оператор switch не похож на инструкцию if-then-else. Оператор switch имеет несколько путей выполнения.

В Documentation состоянии:

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

0

Правильное поведение. «default» не означает все возможные ответы. Это означает, что все ответы без них написаны в случаях.

int x=1 
switch(x) 
    { 
     default: 
      System.out.println("no value found"); 
     case 1: 
      System.out.println("1"); 
     case 2: 
      System.out.println("2"); 
    } 

напечатает

1 
2 

не печатать

no value found 
1 
2 

при использовании перерывов; операторам и значению по умолчанию для каждого значения вызывается только одна «ветвь».

0

Каждый оператор break прекращает действие заключенного оператора. Все утверждения после метки совпадения выполняются в последовательности, независимо от выражения последующих меток case, до тех пор, пока не будет встречен оператор break.

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

Смежные вопросы