สิ่งแรกที่ต้องจำไว้ก็คือผู้ประกอบการที่ประกอบไปด้วย 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