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:
„Każda stała przypadku powiązana z instrukcją switch musi być przypisana zgodnie z typem wyrażenia instrukcji switch ( §5.2 ).”
Oznacza to, że 'a'
należy go odpowiednio przypisać Integer
i Byte
.
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żda char
wartość zmieści się w int
.)
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ń.
„Konteksty przypisania umożliwiają użycie jednego z poniższych :
- konwersja tożsamości (§5.1.1)
- poszerzająca się prymitywna konwersja (pkt 5.1.2)
- rozszerzenie konwersji odniesienia (pkt 5.1.5)
- poszerzenie konwersji odniesienia, po której następuje rozpakowanie
- konwersja odniesienia poszerzająca, po której następuje konwersja rozpakowywania, a następnie konwersja pierwotna poszerzająca
- konwersja boksu (pkt 5.1.7)
- konwersja boksu, po której następuje konwersja rozszerzającego odniesienia
- konwersja rozpakowywania (pkt 5.1.8)
- konwersja rozpakowywania, po której następuje poszerzanie pierwotnej konwersji ”.
Aby przejść od 'a'
do Integer
, musielibyśmy 1 poszerzyć char
wartość do int
pola a następnie int
do Integer
. 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'
aby Integer
nie jest dozwolone. To wyjaśnia błąd kompilacji w pierwszym przypadku.
Można by pomyśleć, że 'a'
do Byte
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.
„Ponadto, jeśli wyrażenie jest ciągłym wyrażeniem ( § 15.28 ) typu bajt, krótki, char lub int:
Zwężenie pierwotnej konwersji można zastosować, jeśli zmienna jest typu bajt, krótka lub char, a wartość stałego wyrażenia jest reprezentatywna dla typu zmiennej.
Zwężenie pierwotnej konwersji, po której następuje konwersja boksu, można zastosować, jeśli zmienna jest typu Byte
, Short
lub Character
, a wartość stałego wyrażenia jest reprezentowalna odpowiednio w bajcie typu, skrócie lub znaku. ”
Drugi z nich odnosi się do 'a'
celu Byte
, ponieważ:
- dosłowny znak jest ciągłym wyrażeniem i
- wartość
'a'
jest 97
dziesiętna, która mieści się w zakresie dla byte
( -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 Java Integer
. Możesz użyć rozszerzającej konwersji odniesienia tylko wtedy, gdy typ źródła jest podtypem typu docelowego.