Alasannya agak rumit, tetapi semuanya ada dalam rincian ( cetak halus jika Anda suka) dari Spesifikasi Bahasa Jawa.
Pertama, JLS 14.11 mengatakan yang berikut tentang switch
pernyataan:
"Setiap konstanta kasus yang terkait dengan pernyataan sakelar harus sesuai dengan jenis Ekspresi pernyataan sakelar ( §5.2 )."
Ini berarti bahwa 'a'
perlu ditugaskan Integer
dan Byte
masing - masing.
Tapi itu tidak terdengar benar:
Anda akan berpikir bahwa karena 'a'
harus ditugaskan ke Integer
karena char
-> int
tugas adalah sah. ( char
Nilai apa pun akan cocok dengan int
.)
Anda akan berpikir bahwa karena 'a'
TIDAK boleh ditugaskan ke Byte
karena char
-> byte
tugas TIDAK sah. (Sebagian besar char
nilai tidak akan masuk ke dalam byte.)
Faktanya, tidak ada yang benar. Untuk memahami mengapa, kita perlu membaca apa sebenarnya JLS 5.2 tentang apa yang diperbolehkan dalam konteks penugasan.
"Konteks penugasan memungkinkan penggunaan salah satu dari berikut ini :
- konversi identitas (§5.1.1)
- konversi pelebaran primitif (§5.1.2)
- konversi referensi pelebaran (§5.1.5)
- konversi referensi pelebaran diikuti oleh konversi unboxing
- konversi referensi pelebaran diikuti oleh konversi unboxing, kemudian diikuti oleh konversi primitif pelebaran
- konversi tinju (§5.1.7)
- konversi tinju diikuti oleh konversi referensi pelebaran
- konversi unboxing (§5.1.8)
- konversi unboxing diikuti oleh konversi primitif pelebaran. "
Untuk beralih dari 'a'
ke Integer
, kita perlu 1 memperluas char
nilai ke int
kotak lalu int
ke Integer
. Tetapi jika Anda melihat kombinasi konversi yang diizinkan, Anda tidak dapat melakukan konversi primitif pelebaran diikuti oleh konversi tinju.
Karenanya 'a'
untuk Integer
tidak diperbolehkan. Ini menjelaskan kesalahan kompilasi dalam kasus pertama.
Anda akan berpikir bahwa 'a'
untuk Byte
tidak diizinkan karena itu akan melibatkan konversi penyempitan primitif ... yang tidak ada dalam daftar sama sekali. Padahal, literal adalah kasus khusus. JLS 5.2 selanjutnya mengatakan yang berikut.
"Selain itu, jika ekspresi adalah ekspresi konstan ( §15.28 ) dari tipe byte, pendek, char, atau int:
Konversi penyempitan primitif dapat digunakan jika variabelnya adalah tipe byte, pendek, atau char, dan nilai ekspresi konstan dapat diwakili dalam jenis variabel.
Konversi penyempitan primitif diikuti oleh konversi tinju dapat digunakan jika variabel bertipe Byte
,, Short
atau Character
, dan nilai ekspresi konstan diwakili dalam byte jenis, pendek, atau karakter masing-masing. "
Yang kedua ini berlaku 'a'
untuk Byte
, karena:
- karakter literal adalah ekspresi yang konstan, dan
- nilai
'a'
adalah 97
desimal, yang berada dalam jangkauan untuk byte
( -128
untuk +127
).
Ini menjelaskan mengapa tidak ada kesalahan kompilasi dalam contoh kedua.
1 - Kita tidak bisa kotak 'a'
untuk Character
kemudian melebar Character
ke Integer
karena Character
tidak subtipe Jawa Integer
. Anda hanya dapat menggunakan konversi referensi pelebaran jika jenis sumber adalah subtipe dari jenis target.