답변:
때로는 동일한 코드 블록과 관련된 여러 사례를 갖는 것이 도움이됩니다.
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
등. 단지 예입니다.
내 경험상 일반적으로 "넘어가는"스타일이 좋지 않고 한 경우에 여러 개의 코드 블록을 실행하는 것이 좋지만 상황에 따라 사용할 수도 있습니다.
// Intentional fallthrough.중단을 생략 할 때는 항상 줄을 따라 주석을 추가하십시오 . 제 생각에는 "실수로 휴식을 잊기 쉬운"것만 큼 나쁜 스타일은 아닙니다. 추신 물론 대답 자체처럼 간단한 경우는 아닙니다.
cases가 그런 식으로 쌓이면 주석을 다룰 필요가 없습니다 . 그들 사이에 코드가 있으면 예, 주석은 아마도 가치가 있습니다.
case에서 여러 케이스를 선언 할 수있는 언어를 상상합니다 case 'A','B','C': doSomething(); case 'D','E': doSomethingElse();. Pascal은 다음과 같이 할 수 있습니다. "case 문은 상수, 하위 범위 또는 쉼표로 구분 된 목록 일 수있는 각 선택자와 서수 표현식의 값을 비교합니다." ( wiki.freepascal.org/Case )
Java는 C에서 왔으며 이것이 C의 구문입니다.
여러 case 문이 하나의 실행 경로 만 갖기를 원하는 경우가 있습니다. 다음은 한 달에 며칠을 알려주는 샘플입니다.
class SwitchDemo2 {
public static void main(String[] args) {
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) )
numDays = 29;
else
numDays = 28;
break;
default:
System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
실수라고 생각합니다. 언어 구조 break로서 기본값 만큼이나 쉽게 fallthrough키워드 를 가지고 있습니다 . 내가 작성하고 읽은 대부분의 코드는 모든 경우마다 중단됩니다.
continue <case name>어떤 case 문을 계속할 것인지 명시 적으로 지정할 수있는 방법을 제안하고 싶습니다 .
case현재 내에서 임의의 것을 허용 할 때 switch이것은 단순히 goto. ;-)
케이스 폴스 루로 모든 종류의 흥미로운 일을 할 수 있습니다.
예를 들어 모든 경우에 특정 작업을 수행하고 싶지만 특정 경우에는 해당 작업과 다른 작업을 수행하고 싶다고 가정 해 보겠습니다. fall-through와 함께 switch 문을 사용하면 매우 쉽게 할 수 있습니다.
switch (someValue)
{
case extendedActionValue:
// do extended action here, falls through to normal action
case normalActionValue:
case otherNormalActionValue:
// do normal action here
break;
}
물론 break사건이 끝날 때 그 진술 을 잊어 버리고 예상치 못한 동작을 유발 하기 쉽습니다 . 좋은 컴파일러는 break 문을 생략하면 경고합니다.
컴파일러가 스위치의 각 코드 블록 뒤에 자동으로 break 문을 넣지 않는 이유는 무엇입니까?
여러 경우 (특별한 경우 일 수 있음)에 대해 동일한 블록을 사용할 수 있다는 좋은 욕망을 제쳐두고 ...
역사적 이유 때문입니까? 여러 코드 블록을 언제 실행하고 싶습니까?
주로 C와의 호환성을위한 것이며 goto키워드가 지구를 돌아 다니던 옛날부터의 고대 해킹 일 것입니다 . 그것은 않습니다 같은 물론 몇 가지 놀라운 일들 활성화 더프의 장치를 하지만, 그 여부는 유리한 점은 나입니다 ... 논란의 여지가 최선을 상대로.
break후 스위치 case들 스위치 문에서 위해 fallthrough을 방지하기 위해 사용된다. 흥미롭게도 JEP-325 를 통해 구현 된 새로 형성된 스위치 레이블을 통해이 작업을 수행 할 수 있습니다 .
이러한 변경 사항으로 인해 추가 시연 된대로 break모든 스위치 case를 사용하지 않아도됩니다.
public class SwitchExpressionsNoFallThrough {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int value = scanner.nextInt();
/*
* Before JEP-325
*/
switch (value) {
case 1:
System.out.println("one");
case 2:
System.out.println("two");
default:
System.out.println("many");
}
/*
* After JEP-325
*/
switch (value) {
case 1 ->System.out.println("one");
case 2 ->System.out.println("two");
default ->System.out.println("many");
}
}
}
일 JDK-12와, 상기 코드를 실행하는 상기 비교 출력 으로 볼 수
//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
과
//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
물론 변경되지 않은 것은
// input
3
many // default case match
many // branches to 'default' as well
따라서 동일한 작업을 수행하기 위해 여러 경우가 필요한 경우 코드를 반복 할 필요가 없습니다.
case THIS:
case THAT:
{
code;
break;
}
또는 다음과 같은 작업을 수행 할 수 있습니다.
case THIS:
{
do this;
}
case THAT:
{
do that;
}
캐스케이드 방식으로.
저에게 물어 보면 버그 / 혼란이 발생하기 쉽습니다.
do this하고 do that이를 위해 그러나 다만 do that그것을 위해?
역사적 기록에 관한 한 Tony Hoare는 1960 년대 "구조화 된 프로그래밍"혁명 기간 동안 사례 진술을 발명했습니다. Tony의 case 문은 케이스 당 여러 레이블을 지원하고 악취가 나는 break문 이없는 자동 종료를 지원했습니다 . 명시 적 요구 사항 break은 BCPL / B / C 라인에서 나온 것입니다. Dennis Ritchie는 다음과 같이 씁니다 (ACM HOPL-II에서).
예를 들어, BCPL switchon 문에서 이스케이프하는 endcase는 1960 년대에 배웠을 때 언어에 존재하지 않았으므로 B 및 C switch 문에서 탈출하기 위해 break 키워드를 오버로딩 한 것은 의식이 아닌 진화의 발산 때문입니다. 변화.
BCPL에 대한 역사적 저작을 찾을 수 없었지만 Ritchie의 의견은 그것이 break다소 역사적 사고 였다는 것을 암시합니다 . BCPL은 나중에 문제를 해결했지만 아마도 Ritchie와 Thompson은 그러한 세부 사항을 신경 쓰기에는 유닉스를 발명하는데 너무 바빴습니다. :-)
break"다중 코드 블록 실행"을 허용 한다는 것을 이미 알고 있으며이 설계 선택의 동기에 더 관심이 있습니다. 다른 사람들은 C에서 Java에 이르기까지 잘 알려진 유산을 언급했으며이 답변은 연구를 C 이전 시대로 훨씬 더 밀어 붙였습니다. 나는 우리가 처음부터이 (아주 원시적이지만) 패턴 매칭이 있었으면 좋겠다.
Java는 C에서 파생되었으며 그 유산에는 Duff 's Device 라는 기술이 포함되어 있습니다. 이는 break;명령문 이없는 경우 제어가 한 사례에서 다음 사례로 넘어 간다는 사실에 의존하는 최적화입니다 . C가 표준화 될 무렵에는 "야생"과 같은 코드가 많았으며 이러한 구조를 깨기 위해 언어를 변경하는 것은 비생산적이었을 것입니다.
사람들이 전에 말했듯이 낙하를 허용하는 것이며 실수가 아니라 기능입니다. 너무 많은 break문이 짜증나는 경우 return대신 문 을 사용하여 쉽게 삭제할 수 있습니다 . 메서드는 가독성과 유지 관리를 위해 가능한 한 작아야하기 때문에 실제로 좋은 switch방법입니다. 따라서 문은 메서드에 대해 이미 충분히 커야합니다. 따라서 좋은 메서드는 다른 것을 포함해서는 안됩니다. 예 :
public class SwitchTester{
private static final Log log = LogFactory.getLog(SwitchTester.class);
public static void main(String[] args){
log.info(monthsOfTheSeason(Season.WINTER));
log.info(monthsOfTheSeason(Season.SPRING));
log.info(monthsOfTheSeason(Season.SUMMER));
log.info(monthsOfTheSeason(Season.AUTUMN));
}
enum Season{WINTER, SPRING, SUMMER, AUTUMN};
static String monthsOfTheSeason(Season season){
switch(season){
case WINTER:
return "Dec, Jan, Feb";
case SPRING:
return "Mar, Apr, May";
case SUMMER:
return "Jun, Jul, Aug";
case AUTUMN:
return "Sep, Oct, Nov";
default:
//actually a NullPointerException will be thrown before reaching this
throw new IllegalArgumentException("Season must not be null");
}
}
}
실행은 다음을 인쇄합니다.
12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
예상대로.
컴파일러에서 자동 중단을 추가하지 않으면 스위치 / 케이스를 사용하여 1 <= a <= 31과 2에서 break 문을 제거하는 것과 같은 조건을 테스트 할 수 있습니다 .
switch(a) {
case 1: //I'm between 1 and 3
case 2: //I'm between 1 and 3
case 3: //I'm between 1 and 3
break;
}
오래된 질문이지만 실제로는 오늘 break 문없이 case를 사용했습니다. break를 사용하지 않는 것은 실제로 다른 함수를 순서대로 결합해야 할 때 매우 유용합니다.
예 : http 응답 코드를 사용하여 시간 토큰으로 사용자 인증
서버 응답 코드 401-토큰이 만료 됨-> 토큰을 재생성하고 사용자 로그인.
서버 응답 코드 200-토큰이 정상입니다-> 사용자 로그인.
케이스 진술 :
case 404:
case 500:
{
Log.v("Server responses","Unable to respond due to server error");
break;
}
case 401:
{
//regenerate token
}
case 200:
{
// log in user
break;
}
이것을 사용하면 토큰이 재생성 될 때 런타임이 케이스 200으로 점프하기 때문에 401 응답에 대해 로그인 사용자 함수를 호출 할 필요가 없습니다.
다른 유형의 숫자, 월, 개수를 쉽게 구분하여 만들 수 있습니다.
이 경우에는 이것이 더 좋습니다.
public static void spanishNumbers(String span){
span = span.toLowerCase().replace(" ", "");
switch (span){
case "1":
case "jan": System.out.println("uno"); break;
case "2":
case "feb": System.out.println("dos"); break;
case "3":
case "mar": System.out.println("tres"); break;
case "4":
case "apr": System.out.println("cuatro"); break;
case "5":
case "may": System.out.println("cinco"); break;
case "6":
case "jun": System.out.println("seis"); break;
case "7":
case "jul": System.out.println("seite"); break;
case "8":
case "aug": System.out.println("ocho"); break;
case "9":
case "sep": System.out.println("nueve"); break;
case "10":
case "oct": System.out.println("diez"); break;
}
}
나는 지금 break내 switch 문 에서 필요한 프로젝트에서 작업 중입니다. 그렇지 않으면 코드가 작동하지 않습니다. 저를 참아 break주시면 switch 문 에 왜 필요한지 좋은 예를 들어 드리겠습니다 .
사용자가 숫자를 입력 할 때까지 대기하는 상태,이를 계산하는 두 번째 상태, 합계를 인쇄하는 세 번째 상태의 세 가지 상태가 있다고 가정 해보십시오.
이 경우 다음이 있습니다.
상태를 보면, 당신은 수렴의 순서에 시작하려는 것입니다 상태 1 다음, 상태 3 마지막 상태 2 . 그렇지 않으면 합계를 계산하지 않고 사용자 입력 만 인쇄합니다. 다시 명확히하기 위해 사용자가 값을 입력 할 때까지 기다린 다음 합계를 계산하고 합계를 인쇄합니다.
다음은 예제 코드입니다.
while(1){
switch(state){
case state1:
// Wait for user input code
state = state3; // Jump to state3
break;
case state2:
//Print the sum code
state = state3; // Jump to state3;
case state3:
// Calculate the sum code
state = wait; // Jump to state1
break;
}
}
우리가 사용하지 않을 경우 break,이 순서에 실행됩니다 상태 1 , 상태 2 및 상태 3 . 그러나를 사용 break하면이 시나리오를 피하고 state1, state3, 마지막으로 state2로 시작하는 올바른 절차를 주문할 수 있습니다.
break.