Java 스위치 내에서 변수 선언 및 초기화
Java 스위치에 대해 미친 질문이 있습니다.
int key = 2;
switch (key) {
case 1:
int value = 1;
break;
case 2:
value = 2;
System.out.println(value);
break;
default:
break;
}
시나리오 1- key
값이 2이면 적용으로 값을 2로 인쇄합니다.
시나리오 2- 주석 value = 2
을 case 2:
달면 지역 변수 값이 초기화 될 수 있습니다 .
질문 :
시나리오 1 : 실행 흐름이 case 1:
(일 때 key = 2
) 로 이동하지 않는 변수의 유형을 어떻게 알 수 있습니까? int
있습니까?
시나리오 2 : 컴파일러가 값 변수의 유형을 알고 있으면 됩니다. (선언 및 초기화) int
의 int value = 1;
자주에 액세스해야합니다 case 1:
. 그럼 왜 그것이 내가 언급을 할 때 sqawrk 수행 value = 2
의 case 2:
속담, 초기화되지 않은 일 수 지역 변수의 값을 .
Switch 문은 기본적으로 범위 지정 지상에서 이상합니다. 에서 JLS의 섹션 6.3 :
블록 (§14.4)에서 변수 선언의 범위는 선언 할 지역 나머지 블록으로, 자체 이니셜 라이저로 시작하고 지역 변수 선언문의 오른쪽에있는 추가 선언을 포함합니다.
귀하의 경우, case 2
는 실행되지 않더라도 동일한 블록 에 case 1
있고 그 뒤 6 나타납니다 case 1
. 따라서 논리적으로 선언을 "실행"않아도하지 지역 변수가 범위 내에 있고 쓰기가 가능합니다 . (초기화가 가능하지만 선언은 "실행 가능"하지 않습니다.)
value = 2;
할당 을 주석 처리 하면 컴파일러는 여전히 참조하는 변수를 알고 싶습니다 값을 할당하는 실행 경로를 거치지 갑자기 기 때문에 시도 할 때와 같은 오류가 발생합니다. 명확하게 할당되지 않은 다른 지역 변수를 읽습니다.
경우에 선언 다른 된 지역 변수를 사용 하지 않는 것이 좋습니다 . 지금까지 본 것처럼 코드를 매우 혼란스럽게 만듭니다. switch 문에 지역 변수를 도입 할 때 (드물게 시도하는 경우-사례가 매우 짧아야합니다. 이상적으로는) 일반적으로 새로운 범위를 도입하는 것을 선호합니다.
case 1: {
int value = 1;
...
break;
}
case 2: {
int value = 2;
...
break;
}
나는 이것이 더 명확하다고 믿습니다.
변수가 선언 (int로) 초기화되지 않은 (초기 값이 할당 됨). 라인을 생각해 봐.
int value = 1;
같이 :
int value;
value = 1;
이int value
부분은 컴파일 타임에 int 인 value라는 변수가 있음을 컴파일러에게 알려줍니다. value = 1
부분을 초기화하지만 실행 시간에 발생, 스위치의 해당 분기를 입력하지 않으면 전혀 발생하지 않습니다.
선언은 타임에 처리하고 코드의 실행 흐름에 의존하지 않습니다.
value
스위치 블록의 로컬 범위 내에서 선언 될 선언 지점에서 해당 블록의 모든 위치에서 사용할 수 있습니다.
JEP 325 : JDK-12 얼리 액세스 빌드의 Switch Expressions (미리보기) 통합으로 . 에서 볼 수있는 특정 변화가 존 의 대답은 -
로컬 변수 범위 -스위치 케이스의 로컬 변수는 이제 전체 스위치 블록 대신 케이스 자체에 로컬이 될 수 있습니다.
Day
추가 설명을 위해 enum 클래스를고려한 예제 (Jon이 구문 론적으로 시도한 것과 유사 함):public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } // some another method implementation Day day = Day.valueOf(scanner.next()); switch (day) { case MONDAY,TUESDAY -> { var temp = "mon-tue"; System.out.println(temp); } case WEDNESDAY,THURSDAY -> { var temp = Date.from(Instant.now()); // same variable name 'temp' System.out.println(temp); } default ->{ var temp = 0.04; // different types as well (not mandatory ofcourse) System.out.println(temp); } }
Switch Expressions- 의도가 변수에 값을 할당 한 다음 사용하려는 경우 스위치 표현식을 사용할 수 있습니다. 예 :
private static void useSwitchExpression() { int key = 2; int value = switch (key) { case 1 -> 1; case 2 -> 2; default -> {break 0;} }; System.out.println("value = " + value); // prints 'value = 2' }
이 설명이 도움이 될 수 있습니다.
int id=1;
switch(id){
default:
boolean b= false; // all switch scope going down, because there is no scope tag
case 1:
b = false;
case 2:{
//String b= "test"; you can't declare scope here. because it's in the scope @top
b=true; // b is still accessible
}
case 3:{
boolean c= true; // case c scope only
b=true; // case 3 scope is whole switch
}
case 4:{
boolean c= false; // case 4 scope only
}
}
자바 사양 :
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.11
레이블이있는 중단으로 인한 갑작스러운 완료의 경우 레이블이있는 문에 대한 일반 규칙 (§14.7)에 의해 처리됩니다.
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.7
라벨이있는 진술 :
LabeledStatement : 식별자 : 문
LabeledStatementNoShortIf : 식별자 : StatementNoShortIf
C 및 C ++와 달리 Java 프로그래밍 언어에는 goto 문이 없습니다. 식별자 문 레이블은 레이블이있는 문 내 어디에서나 나타나는 break (§14.15) 또는 continue (§14.16) 문과 함께 사용됩니다.
레이블이있는 명령문의 레이블 범위는 즉시 포함 된 명령문입니다.
즉, case 1, case 2는 switch 문 내의 레이블입니다. break 및 continue 문을 레이블에 적용 할 수 있습니다.
레이블은 문의 범위를 공유하므로 레이블 내에 정의 된 모든 변수는 switch 문의 범위를 공유합니다.
'IT' 카테고리의 다른 글
ActionBar에서 사용자 정의보기를 표시하는 방법은 무엇입니까? (0) | 2020.09.01 |
---|---|
리디렉션 후 Google 개발자 도구 '네트워크'탭이 지워짐 (0) | 2020.09.01 |
Pandas GroupBy.agg ()를 사용하여 동일한 열의 여러 가지 상품 (0) | 2020.09.01 |
C ++ 03 throw () 지정자 C ++ 11 noexcept의 차이점 (0) | 2020.09.01 |
Python에서 링크를 열거 형으로 변환 (0) | 2020.09.01 |