답변:
때로는 동일한 코드 블록과 관련된 여러 사례를 갖는 것이 도움이됩니다.
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
등. 단지 예입니다.
내 경험상 일반적으로 "넘어가는"스타일이 좋지 않고 한 경우에 여러 개의 코드 블록을 실행하는 것이 좋지만 상황에 따라 사용할 수도 있습니다.
// Intentional fallthrough.
중단을 생략 할 때는 항상 줄을 따라 주석을 추가하십시오 . 제 생각에는 "실수로 휴식을 잊기 쉬운"것만 큼 나쁜 스타일은 아닙니다. 추신 물론 대답 자체처럼 간단한 경우는 아닙니다.
case
s가 그런 식으로 쌓이면 주석을 다룰 필요가 없습니다 . 그들 사이에 코드가 있으면 예, 주석은 아마도 가치가 있습니다.
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 <= 3
1과 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
.