컴파일하지 않습니다 :
void test(Integer x) {
switch (x) {
case 'a':
}
}
컴파일 OK :
void test(Byte x) {
switch(x) {
case 'a':
}
}
답변
그 이유는 다소 복잡하지만 Java 언어 사양 의 세부 사항 ( 원하는 경우 미세 인쇄 )에 모두 있습니다.
우선, JLS 14.11 은 다음과 같은 switch
진술 에 대해 말합니다 .
“스위치 명령문과 연관된 모든 상수는 스위치 명령문의 표현식 유형 ( §5.2 ) 과 호환 가능한 지정이어야합니다 .”
즉 , 각각에 'a'
할당 할 수 있어야합니다 .Integer
Byte
그러나 그것은 제대로 들리지 않습니다.
-
왜냐하면 -> 할당이 합법적 이므로 할당 가능
'a'
해야 한다고 생각할 것 입니다 . (모든 값은에 맞습니다 .)Integer
char
int
char
int
-
-> 할당이 합법적이지 않기 때문에 할당 할
'a'
수 없다고 생각할 것 입니다 . (대부분의 값은 바이트에 맞지 않습니다.)Byte
char
byte
char
실제로, 이들 중 어느 것도 맞지 않습니다. 이유를 이해하려면 할당 컨텍스트에서 허용되는 내용에 대한 JLS 5.2 내용을 읽어야 합니다.
“할당 컨텍스트를 사용 하면 다음 중 하나를 사용할 수 있습니다 .
- 신원 전환 (§5.1.1)
- 확대 원시 변환 (§5.1.2)
- 확대 참조 변환 (§5.1.5)
- 확장 참조 변환 후 언 박싱 변환
- 확장 참조 변환, 언 박싱 변환, 확장 기본 변환
- 권투 변환 (§5.1.7)
- 복싱 변환 후 확장 참조 변환
- 언 박스 변환 (§5.1.8)
- 언 박싱 전환 후 확장 원시 전환이 뒤따 랐습니다. “
에서 'a'
로 이동하려면 값을 1로 확장 한 다음 상자 를로 확장 Integer
해야 합니다 . 그러나 허용되는 전환 조합을 살펴보면 확장 기본 전환 후 복싱 전환을 수행 할 수 없습니다.char
int
int
Integer
따라서 'a'
할 Integer
수 없습니다. 첫 번째 경우의 컴파일 오류에 대해 설명합니다.
당신은 생각 'a'
에 Byte
허용되는 모든의 목록에없는 원시적 축소 변환을 … 포함하기 때문. 실제로 리터럴은 특별한 경우입니다. JLS 5.2 는 다음과 같이 말합니다.
“또한 표현식이 byte, short, char 또는 int 유형 의 상수 표현식 ( §15.28 ) 인 경우 :
변수가 byte, short 또는 char 유형이고 상수 표현식의 값이 변수 유형으로 표시되는 경우 축소 기본 변환이 사용될 수 있습니다.
변수의 유형
Byte
이Short
,, 또는Character
이고 상수 표현식의 값이 각각 바이트, 짧은 또는 문자로 표시 될 수있는 경우 축소 기본 변환과 복싱 변환이 사용될 수 있습니다 . “
이들의 두 번째 적용 'a'
으로 Byte
, 때문에 :
- 문자 리터럴은 상수 표현식이며
- 의 값
'a'
은97
10 진수이며byte
(-128
~+127
) 범위 내에 있습니다.
이것은 두 번째 예에서 컴파일 오류가없는 이유를 설명합니다.
1 – 우리는 상자 수 없습니다 'a'
A를 Character
한 후 확대 Character
에 Integer
있기 때문에 Character
의 자바 하위하지 않습니다 Integer
. 소스 유형이 대상 유형의 하위 유형 인 경우 확대 참조 변환 만 사용할 수 있습니다.