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 switchoś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ć Integeri Byte .
Ale to nie brzmi dobrze:
Można by pomyśleć, że skoro 'a' należy przypisać do, Integerponieważ char-> int przypisanie jest legalne. (Każda charwartość zmieści się w int.)
Można by pomyśleć, że ponieważ 'a' NIE powinno się go przypisywać, Byteponieważ char-> byte przypisanie NIE jest legalne. (Większość charwartoś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ć charwartość do intpola a następnie intdo 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 Integernie jest dozwolone. To wyjaśnia błąd kompilacji w pierwszym przypadku.
Można by pomyśleć, że 'a'do Bytejest 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, Shortlub 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 97dziesiętna, która mieści się w zakresie dla byte( -128do +127).
To wyjaśnia, dlaczego w drugim przykładzie nie ma błędu kompilacji.
1 - Nie możemy wstawić pola 'a'do a, Charactera następnie rozszerzyć Characterdo, Integerponieważ Characternie jest to podtyp Java Integer. Możesz użyć rozszerzającej konwersji odniesienia tylko wtedy, gdy typ źródła jest podtypem typu docelowego.