2013-02-20 28 views
5

आप निम्न कोड चलाते हैं,एक अशक्त बॉक्स्ड वस्तु अनबॉक्सिंग फेंकता अप्रत्याशित NullPointerException

public class Foo{ 
    public static void main(String[] args){ 
     int id = new Bar().getId(); // throws unexpected NullPointerException 
    } 

    private static class Bar{ 
     private final Integer id; 

     public Bar(){ 
      this(null); 
     } 

     public Bar(Integer id){ 
      this.id = id; 
     } 

     public Integer getId(){ 
      return id; 
     } 
    } 
} 

,

Exception in thread "main" java.lang.NullPointerException 
    at Foo.main(Foo.java:3) 

कैसे आ वहाँ कोई संकलक चेतावनी या कुछ भी है आप निम्नलिखित स्टैकट्रेस मिलेगा? IMHO यह अनबॉक्सिंग के साथ एक बहुत ही बुरा subtlety है, या शायद मैं सिर्फ मूर्ख हूँ।


@Javier द्वारा प्रदान की जवाब देने के लिए पर जोड़ने, यदि आप ग्रहण का उपयोग कर रहे हैं, तो आप सक्षम करने के लिए इस निम्नलिखित कार्य करने होंगे:

  1. नेविगेट विंडो को>पसंद>जावा>कंपाइलर>त्रुटियां/चेतावनियां
  2. विस्तृत संभावित प्रोग्रामिंग समस्याओं
  3. टॉगल मुक्केबाजी और unboxing रूपांतरण या तो "चेतावनी" के लिए, या "त्रुटि"
  4. नल "ठीक है"
+0

मुझे समझ में नहीं आता है। क्या आप पूछ रहे हैं कि एनपीई क्यों होता है या यह सिर्फ एक राग है? विशिष्ट उत्तरदायी सवाल क्या होगा? – madth3

उत्तर

5

मैं तुम्हें क्या आईडीई उपयोग कर रहे हैं पता नहीं है , लेकिन ग्रहण और अनबॉक्सिंग रूपांतरणों पर चेतावनी को सक्षम करने के लिए ग्रहण का विकल्प है। इसे शून्य सूचक पहुंच के रूप में पहचानना संभव नहीं है, क्योंकि शून्य को तुरंत अनबॉक्स नहीं किया जाता है, लेकिन Bar.getId() के माध्यम से।

प्रकार पूर्णांक की अभिव्यक्ति पूर्णांक
Foo.java लाइन में unboxed है 3

+0

मैं ग्रहण का उपयोग ~ 3 वर्षों के लिए कर रहा हूं और मुझे यह नहीं पता था! मिठाई! – mre

+2

यह परेशान है कि ग्रहण बिना बॉक्सिंग के अनबॉक्सिंग चेतावनियां चालू नहीं कर सकता है! दृश्यों के पीछे 'intValue' के बारे में https://bugs.eclipse.org/bugs/show_bug.cgi?id=163065 – Kyle

3

आप एक null पर किसी भी विधि का उपयोग करें या कुछ भी है कि एक null साथ मतलब नहीं है करने की कोशिश करते हैं, तो यह NullPointerException फेंकता है।

Autounboxing [Integer object].intValue() विधि (या इसी तरह) के साथ कार्यान्वित किया गया है, इसलिए यह NullPointerException फेंकता है क्योंकि आपके पास null कोई विधि नहीं आ सकता है।

आशा है कि इससे मदद मिलती है!

+1

+1, धन्यवाद – mre

0

NullPointerException आईडीई की तुलना में RuntimeException कोड को संकलित करते समय पता नहीं लगा सकता है।

इसके बजाए, एक अच्छा अभ्यास अनबॉक्सिंग से पहले शून्य की जांच है।

int getId(){ 
    if(id!=null){ 
     return id; 
    } 
    // return other or throw a checked exception. 
} 
0

पूरी तरह से उचित रन टाइम अपवाद की तरह लगता है। यदि आपका मुख्य कोड था:

public static void main(String[] args){   
    Integer idObj = new Bar().getId(); 
    int id = idObj; // throws NullPointerException 
} 

कोई भी शून्य सूचक अपवाद के बारे में आश्चर्यचकित नहीं होगा। बार क्लास एक शून्य देता है, और एक शून्य ऑब्जेक्ट पॉइंटर को एक साधारण मान में नहीं बदला जा सकता है। आईडी क्लास को कार्यान्वित करने के लिए बार क्लास के कार्यान्वयन को गैर-शून्य मान में बदला जा सकता है।कोड के इस ब्लॉक को बार कक्षा से स्वतंत्र रूप से संकलित किया जा सकता है, और बार वर्ग के गतिशील कार्यकलापों के बारे में धारणा निश्चित रूप से कोड के इस ब्लॉक में कोडित नहीं की जानी चाहिए।

यह शायद स्पष्ट है, लेकिन वास्तविक समाधान के बजाय आईडी सदस्य के लिए int का उपयोग करना है।

private static class Bar{ 
    private final int id; 

    public Bar(){ 
     this(0); 
    } 

    public Bar(int id){ 
     this.id = id; 
    } 

    public int getId(){ 
     return id; 
    } 
} 

(लेकिन मुझे लगता है कि आप पहले से ही इस :-) के बारे में जानते थे)

+0

मैंने यह नहीं कहा कि अपवाद अनुचित था, मैंने कहा कि यह अप्रत्याशित था, खासकर जब से मेरे आईडीई ने डिफ़ॉल्ट रूप से इसे अनदेखा करना चुना। – mre

+0

ठीक है, मैं "अपेक्षित" और "अप्रत्याशित" के आसपास होने की कोशिश कर रहा था। यह एक रन-टाइम अपवाद है, ऐसा कुछ नहीं है जिसे स्थैतिक विश्लेषण से जरूरी रूप से निर्धारित किया जा सके। आप इस स्थिति में आईडीई से कैसे व्यवहार करेंगे? – AgilePro

+0

मुझे उम्मीद है कि आईडीई कम से कम मुझे डिफ़ॉल्ट रूप से चेतावनी दे। जैसे मैंने कहा, मुझे लगता है कि यह एक सुंदर सूक्ष्म रनटाइम अपवाद है। – mre

4

ऐसा लगता है कि इस व्यवहार JDK™ 5.0 Documentation में दर्ज है,

: यह है, तो, कोई समस्या नहीं है .. आप int और Integer के बीच भेद को बड़े पैमाने पर अनदेखा कर सकते हैं, कुछ चेतावनियों के साथ। एक Integer अभिव्यक्ति में शून्य मान हो सकता है। यदि आपका प्रोग्राम ऑटोऑनबॉक्स को शून्य करने का प्रयास करता है, तो यह NullPointerException फेंक देगा।

0

बॉक्सिंग मूल समकक्ष 'int' के लिए इंटीजर जैसे ऑब्जेक्ट कास्टिंग करने के लिए वाक्य रचनात्मक चीनी से अधिक कुछ नहीं है। मूल निवासी नहीं हो सकते हैं लेकिन वस्तुओं कर सकते हैं। मुक्केबाजी तंत्र इन मामलों में NullPointerExceptions को नहीं रोकेगा।