เหตุผลค่อนข้างซับซ้อน แต่ทั้งหมดอยู่ในรายละเอียด ( พิมพ์ได้ดีหากคุณต้องการ) ของ 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
คุณสามารถใช้การแปลงการอ้างอิงที่กว้างขึ้นได้หากประเภทแหล่งที่มาเป็นประเภทย่อยของประเภทเป้าหมาย