สิ่งแรกที่ต้องจำไว้ก็คือผู้ประกอบการที่ประกอบไปด้วย Java มี "ประเภท" และนี่คือสิ่งที่คอมไพเลอร์จะตรวจสอบและพิจารณาไม่ว่าสิ่งที่ประเภทที่แท้จริง / จริงของพารามิเตอร์ที่สองหรือสามคือ ขึ้นอยู่กับปัจจัยหลายประการประเภทผู้ประกอบการที่ถูกกำหนดในรูปแบบที่แตกต่างกันตามที่แสดงในJava Language Specification 15.26
ในคำถามข้างต้นเราควรพิจารณากรณีสุดท้าย:
มิฉะนั้นตัวถูกดำเนินการที่สองและสามเป็นประเภทS1และS2ตามลำดับ ให้T1เป็นชนิดที่เป็นผลมาจากการใช้การแปลงมวยS1และให้T2เป็นชนิดที่เป็นผลมาจากการใช้การแปลงมวยS2 ชนิดของนิพจน์เงื่อนไขคือผลลัพธ์ของการใช้การแปลงการจับภาพ (.15.1.10) กับlub (T1, T2) (§15.12.2.7)
นี่คือไกลโดยกรณีที่ซับซ้อนมากที่สุดเมื่อคุณดูที่การใช้การแปลงจับ (§5.1.10)และส่วนใหญ่ของทั้งหมดในหลุบ (T1, T2)
ในภาษาอังกฤษธรรมดาและหลังจากการทำให้เข้าใจง่ายสุดขีดเราสามารถอธิบายขั้นตอนการคำนวณ "Least Common Superclass" (ใช่ลองคิดถึง LCM) ของพารามิเตอร์ที่สองและสาม สิ่งนี้จะทำให้เราเป็นผู้ประกอบการ "พิมพ์" อีกครั้งสิ่งที่ฉันเพิ่งพูดคือการทำให้เข้าใจง่ายมาก (พิจารณาคลาสที่ใช้อินเทอร์เฟซทั่วไปหลายตัว)
ตัวอย่างเช่นหากคุณลองทำสิ่งต่อไปนี้:
long millis = System.currentTimeMillis();
return(true ? new java.sql.Timestamp(millis) : new java.sql.Time(millis));
คุณจะสังเกตเห็นว่าประเภทของการแสดงออกตามเงื่อนไขนั้นเป็นjava.util.Date
เพราะ "Least Common Superclass" สำหรับTimestamp
/ Time
คู่
เนื่องจากnull
สามารถถูกล็อกอัตโนมัติกับสิ่งใด ๆ "Least Common Superclass" เป็นInteger
คลาสและนี่จะเป็นชนิดส่งคืนของนิพจน์เงื่อนไข (ตัวดำเนินการที่ประกอบไปด้วย) ด้านบน ค่าส่งคืนจะเป็นตัวชี้ null ของประเภทInteger
และนั่นคือสิ่งที่จะถูกส่งกลับโดยผู้ประกอบการที่ประกอบไปด้วย
ณ รันไทม์เมื่อ Java Virtual Machine ยกเลิกการInteger
ทำเครื่องหมาย a NullPointerException
จะถูกส่งออกไป สิ่งนี้เกิดขึ้นเนื่องจาก JVM พยายามเรียกใช้ฟังก์ชันnull.intValue()
ซึ่งnull
เป็นผลมาจากการล็อคอัตโนมัติ
ในความคิดของฉัน (และเนื่องจากความคิดเห็นของฉันไม่ได้อยู่ในข้อกำหนดภาษา Java หลายคนจะพบว่ามันผิดอยู่ดี) คอมไพเลอร์ทำงานได้ไม่ดีในการประเมินการแสดงออกในคำถามของคุณ ระบุว่าคุณเขียนtrue ? param1 : param2
คอมไพเลอร์ควรกำหนดทันทีว่าพารามิเตอร์แรกnull
- จะถูกส่งกลับและควรสร้างข้อผิดพลาดคอมไพเลอร์ นี้จะค่อนข้างคล้ายกับเมื่อคุณเขียนและเรียบเรียงบ่นเกี่ยวกับรหัสใต้ห่วงและธงด้วยwhile(true){} etc...
Unreachable Statements
กรณีที่สองของคุณค่อนข้างตรงไปตรงมาและคำตอบนี้ยาวเกินไปแล้ว ... ;)
แก้ไข:
หลังจากการวิเคราะห์อื่นฉันเชื่อว่าฉันผิดที่จะบอกว่าnull
ค่าสามารถบรรจุ / autoboxed เพื่ออะไร พูดคุยเกี่ยวกับระดับจำนวนเต็มมวยอย่างชัดเจนประกอบด้วยในการอัญเชิญnew Integer(...)
คอนสตรัคหรืออาจจะเป็นInteger.valueOf(int i);
(ผมพบว่ารุ่นนี้อยู่ที่ไหนสักแห่ง) อดีตจะขว้างNumberFormatException
(และสิ่งนี้ไม่เกิดขึ้น) ในขณะที่สองจะไม่สมเหตุสมผลเนื่องจากint
ไม่สามารถnull
...
int foo = (true ? null : 0)
และnew Integer(null)
ทั้งคู่ก็ปรับตัวที่สองคือรูปแบบที่ชัดเจนของการ autobox