Nie kompiluje:
void test(Integer x) {
switch (x) {
case 'a':
}
}
Kompiluje OK:
void test(Byte x) {
switch(x) {
case 'a':
}
}
java
java-8
switch-statement
Ali gh
źródło
źródło
'a'
przypadku zostanie wykonany w przypadku, któryx
jest bajtem97
. (Spróbuj, jeśli mi nie wierzysz). Prawdziwe wyjaśnienie znajduje się w mojej odpowiedzi.Odpowiedzi:
Przyczyny są raczej skomplikowane, ale wszystkie są szczegółowo opisane ( drobnym drukiem, jeśli chcesz) specyfikacji języka Java.
Po pierwsze, JLS 14.11 mówi o
switch
oświadczeniach:Oznacza to, że
'a'
należy go odpowiednio przypisaćInteger
iByte
.Ale to nie brzmi dobrze:
Można by pomyśleć, że skoro
'a'
należy przypisać do,Integer
ponieważchar
->int
przypisanie jest legalne. (Każdachar
wartość zmieści się wint
.)Można by pomyśleć, że ponieważ
'a'
NIE powinno się go przypisywać,Byte
ponieważchar
->byte
przypisanie NIE jest legalne. (Większośćchar
wartości nie mieści się w bajcie).W rzeczywistości żadna z nich nie jest poprawna. Aby zrozumieć, dlaczego, musimy przeczytać, co JLS 5.2 faktycznie mówi o tym, co jest dozwolone w kontekstach przypisań.
Aby przejść od
'a'
doInteger
, musielibyśmy 1 poszerzyćchar
wartość doint
pola a następnieint
doInteger
. Ale jeśli spojrzysz na kombinacje dozwolonych konwersji, nie możesz wykonać rozszerzającej prymitywnej konwersji, po której następuje konwersja boksu.Dlatego
'a'
abyInteger
nie jest dozwolone. To wyjaśnia błąd kompilacji w pierwszym przypadku.Można by pomyśleć, że
'a'
doByte
jest niedozwolone, bo to wiązałoby się z prymitywnego zwężenie konwersji ... który nie ma na liście w ogóle. W rzeczywistości literały są szczególnym przypadkiem. JLS 5.2 mówi dalej.Drugi z nich odnosi się do
'a'
celuByte
, ponieważ:'a'
jest97
dziesiętna, która mieści się w zakresie dlabyte
(-128
do+127
).To wyjaśnia, dlaczego w drugim przykładzie nie ma błędu kompilacji.
1 - Nie możemy wstawić pola
'a'
do a,Character
a następnie rozszerzyćCharacter
do,Integer
ponieważCharacter
nie jest to podtyp JavaInteger
. Możesz użyć rozszerzającej konwersji odniesienia tylko wtedy, gdy typ źródła jest podtypem typu docelowego.źródło
int
jako typu przełącznika? (ponieważchar -> int
dozwolone jest prymitywne poszerzenie)