เหตุผลค่อนข้างซับซ้อน แต่ทั้งหมดอยู่ในรายละเอียด ( พิมพ์ได้ดีหากคุณต้องการ) ของ Java Language Specification
ก่อนอื่นJLS 14.11พูดเกี่ยวกับswitchข้อความต่อไปนี้:
"ค่าคงที่ของทุกกรณีที่เกี่ยวข้องกับคำสั่ง switch จะต้องได้รับการกำหนดให้เข้ากันได้กับชนิดของ Expression ของคำสั่ง switch ( §5.2 )"
ซึ่งหมายความว่า'a'จะต้องกำหนดให้IntegerและByte ตามลำดับ
แต่นั่นไม่ถูกต้อง:
คุณคิดว่า'a' ควรจะมอบหมายให้Integerเพราะchar-> การint มอบหมายนั้นถูกกฎหมาย ( charค่าใด ๆจะพอดีกับ an int.)
คุณจะคิดว่าเนื่องจาก'a' ไม่ควรมอบหมายให้Byteเพราะchar-> การbyte มอบหมายนั้นไม่ถูกกฎหมาย ( charค่าส่วนใหญ่จะไม่พอดีกับไบต์)
ที่จริงแล้วสิ่งเหล่านี้ไม่ถูกต้อง เพื่อทำความเข้าใจว่าทำไมเราต้องอ่านสิ่งที่JLS 5.2จริงเกี่ยวกับสิ่งที่ได้รับอนุญาตในบริบทการมอบหมาย
"บริบทการมอบหมายให้ใช้อย่างใดอย่างหนึ่งต่อไปนี้ :
- การแปลงข้อมูลประจำตัว (§5.1.1)
- การแปลงดั้งเดิมแบบขยับขยาย (§5.1.2)
- การแปลงการอ้างอิงที่กว้างขึ้น (§5.1.5)
- การแปลงการอ้างอิงแบบขยายตามด้วยการแปลงแบบไม่ทำกล่อง
- การแปลงการอ้างอิงแบบขยายตามด้วยการแปลงแบบไม่มีกล่องจากนั้นตามด้วยการแปลงแบบดั้งเดิมแบบขยับขยาย
- การแปลงมวย (§5.1.7)
- การแปลงมวยตามด้วยการแปลงการอ้างอิงที่กว้างขึ้น
- การแปลง unboxing (§5.1.8)
- การแปลงที่ไม่ทำกล่องแล้วตามด้วยการแปลงดั้งเดิมที่เปิดกว้าง "
ที่จะไปจาก'a'การIntegerที่เราจะต้อง1ขยายcharค่าไปยังintแล้วกล่องไปยังint Integerแต่ถ้าคุณดูชุดค่าผสมของการแปลงที่ได้รับอนุญาตคุณจะไม่สามารถทำการแปลงแบบดั้งเดิมได้ตามด้วยการแปลงแบบมวย
ดังนั้น'a'จะIntegerไม่ได้รับอนุญาต สิ่งนี้อธิบายถึงข้อผิดพลาดในการคอมไพล์ในกรณีแรก
คุณจะคิดว่า'a'จะByteไม่ได้รับอนุญาตเพราะนั่นจะเกี่ยวข้องกับการแปลงให้แคบลงดั้งเดิม ... ซึ่งไม่ได้อยู่ในรายการเลย แท้จริงแล้วตัวอักษรเป็นกรณีพิเศษ JLS 5.2พูดต่อไปนี้
"นอกจากนี้หากนิพจน์เป็นนิพจน์คงที่ ( §15.28 ) ของชนิดไบต์, ระยะสั้น, ถ่านหรือ int:
การแปลงดั้งเดิมแบบ จำกัด ให้แคบลงอาจใช้ถ้าตัวแปรเป็นประเภทไบต์สั้นหรือถ่านและค่าของนิพจน์คงที่นั้นสามารถแทนได้ในประเภทของตัวแปร
การกวดขันการแปลงดั้งเดิมตามด้วยการแปลงมวยอาจจะใช้ในกรณีที่ตัวแปรเป็นชนิดByte, ShortหรือCharacterและความคุ้มค่าของการแสดงออกคงเป็นแทนได้ในประเภทไบต์สั้นหรือถ่านตามลำดับ."
ที่สองเหล่านี้นำไปใช้กับ'a'การByteเพราะ:
- ตัวอักษรตัวอักษรคือการแสดงออกอย่างต่อเนื่องและ
- ค่าของ
'a'เป็น97ทศนิยมซึ่งอยู่ในช่วงสำหรับbyte( -128ถึง+127)
สิ่งนี้อธิบายว่าทำไมไม่มีข้อผิดพลาดในการรวบรวมในตัวอย่างที่สอง
1 - เราไม่สามารถกล่อง'a'ไปCharacterแล้วขยายCharacterไปIntegerเพราะไม่ได้เป็นชนิดย่อยของCharacter Java Integerคุณสามารถใช้การแปลงการอ้างอิงที่กว้างขึ้นได้หากประเภทแหล่งที่มาเป็นประเภทย่อยของประเภทเป้าหมาย