2015-01-27 8 views
8

निम्नलिखित NullPointerException क्यों फेंकता है? :विधि वापसी प्रकार में NullPointerException ऑब्जेक्ट

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

मैं जानता हूँ कि अगर मैं के कोड के बाद एक NullPointerException फेंक नहीं होगा कोई एक कार्य करें:

एक)

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : (Object) null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

बी)

public static Object myTest() { 
    Boolean x = false; 
    Boolean y = false; 
    return x && y ? new Object() : x ? x : y ? y : null; 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

इसके अलावा, अगर मैं कोड बदलता हूं ई पूरी तरह से और निम्न उपाय अपनाते हैं यह काम करता है:

public static Object myTest() { 
    boolean x = false; 
    boolean y = false; 

    if(x && y) { 
     return new Object(); 
    } else if(x) { 
     return x; 
    } else if(y) { 
     return y; 
    } else { 
     return null; 
    } 
} 

public static void main(String [ ] args) { 
    myTest(); 
} 

मुझे लगता है कि संकलक एक अनुकूलन के कुछ प्रकार कर रहे हैं और किसी भी तरह चीजों को खिलवाड़ कर रहा है? मुझे लगता है कि यह किसी प्रकार की कास्टिंग समस्या है, लेकिन क्लासकास्ट अपवाद के बजाय उस मामले में यह नलपोइंटर अपवाद क्यों फेंक देगा? यह क्यों हो रहा है इस बारे में कोई भी जानकारी की सराहना की जाएगी!

अग्रिम

+0

यह एक फेंक रहा है NullPointerException क्योंकि उस भयानक गड़बड़ी में कहीं नल पॉइंटर है। –

+0

मैंने शुरुआत में यही सोचा था, लेकिन मुझे लगता है कि यह देखने लायक है, इसलिए +1 – Bathsheba

+0

@laune, यह एक 'NullPointerException' फेंक देता है। –

उत्तर

6

धन्यवाद आप पठनीयता के लिए कुछ कोष्ठक जोड़ते हैं:

return (x && y) ? (new Object()) : (x ? x : (y ? y : null)); 

आप y ? y : null पर देख सकते हैं कि संकलक Unbox को null (ताकि प्रकार से मेल खाते हैं) के कारण का प्रयास करेगा, एक एनपीई फेंक दिया जाएगा।

+2

पूरा करने के लिए: 'y: null' का प्रकार' y' द्वारा सेट किया गया है क्योंकि बाएं ऑपरेंड शून्य है। यदि आप '(ऑब्जेक्ट) नल' जोड़ते हैं, तो आप टाइप को सेट करते हैं, ऑटोऑनबॉक्सिंग को 'बूलियन' पर रोकते हैं, और यदि आप 'बूलियन वाई' जोड़ते हैं, तो अनबॉक्सिंग की आवश्यकता नहीं होती है क्योंकि 'नूल' 'बूलियन' प्रकार में फिट बैठता है। परीक्षण के बाद – njzk2

+2

, एनपीई स्पष्ट रूप से '(x? X: ...) 'पर होता है क्योंकि संकलक सोचता है कि' (y? Y: null) 'का परिणाम' बूलियन 'होना चाहिए – njzk2

+1

@ njzk2 यह संबंधित हो सकता है http : //stackoverflow.com/questions/3882095/booleans-conditional-operators-and-autoboxing अगर हम '(y? y: null)' 'returnNull()' के बराबर के रूप में व्यवहार करेंगे (लेकिन मैंने इसे अभी तक नहीं पढ़ा तो मैं गलत हो सकता है)। – Pshemo

1

(यह कोड अपठनीय है और शायद इससे बचा जाना चाहिए।) लेकिन वास्तव में उत्तर देने के लिए: ऊपर के रूप में, तर्क ऑटोबॉक्सिंग और अनबॉक्सिंग और कंपाइलर चेक करने के साथ करना है। ऐसा लगता है कि आपने boolean b = (Boolean) null लिखा था जो रनटाइम पर एनपीई फेंक देगा।

उदाहरण में ए, आपने इसे ऑब्जेक्ट में स्पष्ट रूप से डाला है, इसलिए कोई ऑटोबॉक्सिंग जोड़ा नहीं गया है।

उदाहरण में बी, सब कुछ पहले से ही एक वस्तु है (बूलियन एक आदिम है, जबकि बूलियन एक वस्तु है), फिर से, कोई मुक्केबाजी या अनबॉक्सिंग नहीं।

अंत में, उदाहरण में सी में कोई अनबॉक्सिंग नहीं है, और इसके परिणामस्वरूप परिणाम लौटाए जाने पर बस बॉक्स किया गया है। (यदि-और शाखाकरण कंपाइलर को प्रत्येक शाखा को अलग-अलग जांचने की अनुमति देता है, तो टर्नरी ऑपरेटरों की बजाय, जो बयान की पूरी तरह से पता लगाने की आवश्यकता होती है और फिर पूरे कथन को एक प्रकार का आवंटन करने की आवश्यकता होती है। इसे बयान बनाम अभिव्यक्तियों और अजीबता के साथ बहुत कुछ करना पड़ता है जावा autoboxing और प्रकार-चेकिंग नियमों में)

(कास्टिंग समस्याओं संकलन समय पर तब होगा, जब की तरह एक असंगत कलाकारों का प्रयास करें:। अगर आप की तरह कुछ करना (Boolean) 7 या रनटाइम पर:

int c = 7; 
Object co = (Object) c; 
Boolean bco = (Boolean) co; 
संबंधित मुद्दे