ध्यान रखने वाली पहली बात यह है कि जावा टर्नरी ऑपरेटरों के पास एक "प्रकार" है, और यह वह है जो संकलक निर्धारित करेगा और विचार करेगा कि कोई दूसरा या तीसरा पैरामीटर वास्तविक / वास्तविक प्रकार क्या है। कई कारकों के आधार पर टर्नरी ऑपरेटर प्रकार को अलग-अलग तरीकों से निर्धारित किया जाता है जैसा कि जावा भाषा विनिर्देश 15.26 में चित्रित किया गया है
उपरोक्त प्रश्न में हमें अंतिम मामले पर विचार करना चाहिए:
अन्यथा, दूसरे और तीसरे ऑपरेशंस क्रमशः S1 और S2 प्रकार के हैं। बता दें कि टी 1 वह प्रकार है जो बॉक्सिंग रूपांतरण को एस 1 में लागू करने से होता है , और टी 2 उस प्रकार का होता है जो बॉक्सिंग रूपांतरण को एस 2 में लागू करने से होता है । सशर्त अभिव्यक्ति का प्रकार लुब (टी 1, टी 2) ( ) 15.12.2.7) पर कब्जा रूपांतरण (.15.1.10) लागू करने का परिणाम है ।
जब तक आप कैप्चर कन्वर्ज़न (.105.1.10) को लागू करते हैं और लुब (T1, T2) पर सबसे अधिक नज़र डालते हैं, यह अब तक का सबसे जटिल मामला है ।
सादे अंग्रेजी में और एक चरम सरलीकरण के बाद हम दूसरे और तीसरे मापदंडों के "लिस्ट कॉमन सुपरक्लास" (हां, एलसीएम के बारे में सोचें) की गणना के रूप में इस प्रक्रिया का वर्णन कर सकते हैं। यह हमें टर्नरी ऑपरेटर "प्रकार" देगा। फिर, जो मैंने अभी कहा वह एक चरम सरलीकरण है (उन वर्गों पर विचार करें जो कई सामान्य इंटरफेस को लागू करते हैं)।
उदाहरण के लिए, यदि आप निम्नलिखित प्रयास करते हैं:
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
किसी भी चीज़ के लिए ऑटोबॉक्स्ड किया जा सकता है, "लिस्ट कॉमन सुपरक्लास" Integer
क्लास है और यह ऊपर दिए गए सशर्त अभिव्यक्ति (टर्नरी ऑपरेटर) का रिटर्न प्रकार होगा। वापसी मूल्य तब एक अशक्त प्रकार का सूचक Integer
होगा और वह है जो टर्नरी ऑपरेटर द्वारा लौटाया जाएगा।
रनटाइम के समय, जब जावा वर्चुअल मशीन Integer
एक NullPointerException
फेंक दिया जाता है। ऐसा इसलिए होता है क्योंकि जेवीएम फ़ंक्शन को लागू करने का प्रयास करता है null.intValue()
, जहां null
ऑटोबॉक्सिंग का परिणाम होता है।
मेरी राय में (और चूंकि मेरी राय जावा लैंग्वेज स्पेसिफिकेशन में नहीं है, वैसे भी कई लोग इसे गलत पाएंगे) कंपाइलर आपके प्रश्न में अभिव्यक्ति का मूल्यांकन करने में खराब काम करता है। यह देखते हुए कि आपने true ? param1 : param2
कंपाइलर को तुरंत यह निर्धारित करना चाहिए कि पहला पैरामीटर - null
- वापस कर दिया जाएगा और इसे एक कंपाइलर त्रुटि उत्पन्न करनी चाहिए। जब आप लिखते हैं तो यह कुछ इसी तरह का होता है while(true){} etc...
और संकलक लूप के नीचे कोड के बारे में शिकायत करता है और इसके साथ झंडे लगाता है Unreachable Statements
।
आपका दूसरा मामला बहुत सीधा है और यह जवाब पहले से ही बहुत लंबा है ...;)
भूल सुधार:
एक और विश्लेषण के बाद मेरा मानना है कि मैं यह कहना गलत था कि किसी null
भी चीज के लिए एक मूल्य को बॉक्सिंग / ऑटोबॉक्स किया जा सकता है। क्लास इंटेगर के बारे में बात करते हुए, स्पष्ट मुक्केबाजी में new Integer(...)
कंस्ट्रक्टर को शामिल करना शामिल है या शायद Integer.valueOf(int i);
(मुझे यह संस्करण कहीं मिला)। पूर्व एक फेंक देगा NumberFormatException
(और ऐसा नहीं होता है), जबकि दूसरा सिर्फ एक के बाद से कोई मतलब int
नहीं होगा null
...
int foo = (true ? null : 0)
औरnew Integer(null)
दोनों संकलन ठीक, दूसरा autoboxing की स्पष्ट रूप से किया जा रहा।