मान निर्दिष्ट करते समय विषम जावा टर्नरी व्यवहार। ऐसा होने के लिए पर्दे के पीछे जावा क्या कर रहा है?


10

कुछ दिनों पहले, मैं एक आकर्षक परिदृश्य में भाग गया कि मुझे कोई प्रलेखन कैसे या क्यों नहीं मिल रहा है जावा निम्नलिखित होने देता है। (यह स्निपेट बग का एक सरलीकृत रूप है।)

    @Test
    public void test() {
      boolean bool = false;
      Integer intVal = Integer.valueOf(5);
      Long longVal = null;
      Long result = bool ? intVal : longVal;

      System.out.println(" > " + result);
   }

ऊपर स्निपेट में:

यदि बूल = सत्य है, तो आपको '5' का मान मिलता है;

लेकिन अगर बूल = गलत है, तो आपको टर्नरी ऑपरेशन का मूल्यांकन करने की कोशिश करते समय एक अशक्त सूचक अपवाद मिलता है। प्रिंट स्टेटमेंट नहीं।


इसे ठीक करने के लिए मैं सिर्फ 'परिणाम' को बदलता हूं

Long result = bool ? Long.valueOf(intVal) : longVal;

ऐसा करने से मुझे अपेक्षित व्यवहार मिलेगा:

यदि बूल = सत्य है, तो आपको '5' का मान मिलता है;

लेकिन अगर बूल = गलत है, तो आप 'अशक्त' हैं


अब मज़े की बात यह है कि यदि आप इसे सामान्य रूप से विभाजित करते हैं / अन्यथा कथन करते हैं, तो जावा आपको संकलित नहीं करता है

longVal = intVal; 

लेकिन यह ternary ऑपरेटर के माध्यम से नहीं पकड़ता है। तो जावा मूल स्निपेट में इसे शून्य बिंदु बनाने के लिए क्या कर रहा है?

(जावा ११)

जवाबों:


10

जब आप ऐसा करते हैं:

Long result = bool ? intVal : longVal

यह एक्सप्रेशन वापस आ रहा है long, जब boolयह गलत है तो यह वेरिएबल nullको फिट करने के लिए लॉन्ग वैल्यू को अनबॉक्स करने की कोशिश करता है resultऔर एनपीई फेंकता है।

जब आप ऐसा करते हैं:

Long result = bool ? Long.valueOf(intVal) : longVal

यह अभिव्यक्ति पहले से ही लौट रही है, Longफिर अनबॉक्सिंग की कोई आवश्यकता नहीं है और nullमान सफलतापूर्वक resultचर को सौंपा गया है।

संदर्भ:

जैसा कि टिप्पणी अनुभाग में चर्चा की गई है, यह समझने के लिए कि ऐसा क्यों होता है, जेएलएस के निम्नलिखित खंडों की जांच करें:


मैं आपको अलग संदर्भ तालिका 15.25 ए से ई तक आश्चर्यचकित करता हूं जहां यह "स्पष्ट" है कि इंटीजर / लॉन्ग रिजल्ट इन बीएनपी (इंटेगर, लॉन्ग)।
मैट

अच्छा उत्तर। आम तौर पर जब मुझे बिल्कुल पता नहीं होता है, तो अंदर क्या चल रहा है, मैं संकलित बायटेकोड में एक नज़र रखने की सलाह देता हूं, जो लगभग बिल्कुल खुलासा करता है, जो वर्णित है। कम से कम एक न्यूनतम कोड स्निपेट निकालते समय, यह कम या ज्यादा प्रशिक्षण का विषय है, इसे कैसे पढ़ें और समझें।
Jan Held

जेएलएस के रूप में , धारा 5.6.2 कहता है: "यदि कोई ऑपरेंड एक संदर्भ प्रकार का है, तो इसे अनबॉक्सिंग रूपांतरण के अधीन किया जाता है"; उसके बाद "व्यापक आदिम रूपांतरण (Wid5.1.2) को लागू किया जाता है [..]"
डिएगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.