java - एक NullPointerException क्या है, और मैं इसे कैसे ठीक करूँ?




(8)

नल पॉइंटर अपवाद क्या हैं ( java.lang.NullPointerException ) और उनका क्या कारण है?

कारणों का निर्धारण करने के लिए कौन से विधियों / उपकरण का उपयोग किया जा सकता है ताकि आप अपवाद को समय से पहले समाप्त करने के लिए प्रोग्राम को समाप्त करने से रोक दें?


जावा में हर चीज कक्षा के रूप में होती है।

यदि आप किसी वस्तु का उपयोग करना चाहते हैं तो आपके पास दो चरण हैं

  1. घोषित
  2. प्रारंभ

उदाहरण:

  • घोषणा: int a;
  • प्रारंभ: a=0;

सरणी अवधारणा के लिए एक ही

  • घोषणा: Item i[]=new Item[5];
  • आरंभ: i[0]=new Item();

यदि आपने प्रारंभिक अनुभाग नहीं दिया है तो NullpointerException उत्पन्न होता है।


किसी NullPointerException की एक और घटना तब होती है जब कोई ऑब्जेक्ट सरणी को घोषित करता है, तब तत्काल उसके अंदर के dereference तत्वों की कोशिश करता है

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

यह विशेष एनपीई टाला जा सकता है यदि तुलना क्रम उलटा हुआ है; अर्थात्, उपयोग की .equals है। गारंटीकृत गैर-अशक्त ऑब्जेक्ट पर .equals

सरणी के अंदर के सभी तत्वों को उनके सामान्य प्रारंभिक मूल्य में आरंभ किया जाता है ; किसी भी ऑब्जेक्ट सरणी के लिए, इसका अर्थ है कि सभी तत्व null

उन्हें प्रवेश या उन्हें कम करने से पहले आप तत्वों को प्रारंभ करना चाहिए

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

एक अशक्त सूचक अपवाद तब होता है जब आप एक वेरिएबल की अनुपयोगी स्थिति को इंगित करते हैं जो null ओर इशारा करते हैं। निम्न कोड देखें:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown

एक NULL पॉइंटर एक है जो कहीं भी नहीं इंगित करता है। जब आप एक सूचक p अनुपस्थिति करते हैं, तो आप कहते हैं "मुझे" में संग्रहित स्थान पर डेटा दें "।" जब p एक अशक्त सूचक है, तो p मौजूद स्थान nowhere , आप कह रहे हैं "मुझे स्थान पर डेटा दें 'कहीं नहीं' "। जाहिर है यह ऐसा नहीं कर सकता है, इसलिए यह एक NULL pointer exception फेंकता NULL pointer exception

सामान्य तौर पर, ऐसा इसलिए है क्योंकि कुछ ठीक से शुरू नहीं किया गया है


एक NullPointerException क्या है?

शुरू करने के लिए एक अच्छी जगह जावा डॉक्स है उन्होंने यह कवर किया है:

फेंक दिया जाता है जब कोई एप्लिकेशन किसी मामले में शून्य का उपयोग करने का प्रयास करता है जहां कोई वस्तु आवश्यक है। इसमें शामिल है:

  • रिक्त ऑब्जेक्ट के उदाहरण विधि को कॉल करना।
  • किसी अशक्त वस्तु के क्षेत्र में प्रवेश करना या संशोधित करना।
  • अशक्त की लंबाई लेना जैसे कि यह एक सरणी थी
  • रिक्त स्थान की स्लॉट तक पहुंच या संशोधित करना जैसे कि यह एक सरणी है
  • नल की तरह फेंकना जैसे वह एक थ्रोहेबल वैल्यू थे।

रिक्त वस्तु के अन्य गैरकानूनी उपयोगों को इंगित करने के लिए आवेदनों को इस वर्ग के उदाहरणों को फेंकना चाहिए।

यह भी ऐसा मामला है कि यदि आप synchronized किसी रिक्त संदर्भ का उपयोग करने का प्रयास करते हैं, तो यह JLS के अनुसार , यह अपवाद फेंक देगा:

SynchronizedStatement:
    synchronized ( Expression ) Block
  • अन्यथा, अगर अभिव्यक्ति का मूल्य शून्य है, तो एक NullPointerException फेंक दिया जाता है।

मैं इसे कैसे ठीक करूं?

तो आपके पास एक NullPointerException , आप इसे कैसे ठीक करते हैं? चलो एक सरल उदाहरण लेते हैं जो एक NullPointerException फेंकता है

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

शून्य मानों को पहचानें

पहला कदम यह पता लगा रहा है कि कौन से मान अपवाद पैदा कर रहे हैं । इसके लिए हमें कुछ डीबगिंग करने की ज़रूरत है। स्टैकट्र्रेस पढ़ने के लिए सीखना महत्वपूर्ण है। यह आपको दिखाएगा कि अपवाद कहाँ फेंका गया था:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

यहां, हम देखते हैं कि अपवाद पंक्ति 13 पर (प्रिंटस्ट्रिंग विधि में) फेंक दिया गया है। पंक्ति को देखें और जांच लें कि कौन से मान रिक्त हैं, लॉगिंग स्टेटमेंट जोड़कर या डीबगर का उपयोग कर। हमें पता चला है कि s शून्य है, और उस पर length विधि को कॉल करने से अपवाद फेंकता है हम देख सकते हैं कि कार्यक्रम अपवाद को फेंकने पर रोकता है जब s.length() विधि से हटा दिया जाता है।

ट्रेस करें कि ये मूल्य कहाँ से आते हैं

आगे की जांच करें कि यह मान कहां से आता है। विधि के कॉल करने वालों का अनुसरण करके, हम देखते हैं कि print() printString(name) के साथ print() विधि में पास किया गया है, और यह। नाम शून्य है।

ट्रेस करें कि इन मानों को कहाँ सेट किया जाना चाहिए

यह कहां है। this.name सेट है? setName(String) विधि में कुछ और डीबगिंग के साथ, हम देख सकते हैं कि इस विधि को बिल्कुल भी नहीं कहा जाता है। यदि विधि को बुलाया गया था, तो सुनिश्चित करें कि ये विधियों को कहा जाता है, और प्रिंट विधि के बाद सेट विधि को नहीं कहा जाता है।

यह हमें समाधान देने के लिए पर्याप्त है: printer.setName() को कॉल करने से पहले printer.setName() को कॉल जोड़ें। printer.print()

अन्य सुधार

चर में एक डिफ़ॉल्ट मान हो सकता है (और setName इसे रिक्त सेट पर रोक सकता है):

private String name = "";

या तो print या printString विधि नल की जांच कर सकती है, उदाहरण के लिए:

printString((name == null) ? "" : name);

या आप वर्ग को डिज़ाइन कर सकते हैं ताकि name हमेशा एक गैर-रिक्त मान हो

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

यह भी देखें:

मुझे अभी भी समस्या नहीं मिल रही है

यदि आप समस्या को डिबग करने की कोशिश करते हैं और अभी भी समाधान नहीं है, तो आप अधिक सहायता के लिए एक प्रश्न पोस्ट कर सकते हैं, लेकिन जो भी आपने कोशिश की है उसे शामिल करना सुनिश्चित करें कम से कम, सवाल में स्टैकट्र्रेस शामिल करें , और कोड में महत्वपूर्ण पंक्ति संख्याओं को चिह्नित करें । साथ ही, पहले कोड को सरल बनाने का प्रयास करें (देखें SSCCE )


कई स्पष्टीकरण पहले से मौजूद हैं कि यह कैसे समझा जाता है कि यह कैसे होता है और कैसे इसे ठीक करें, लेकिन आपको NullPointerException से बचने के लिए सर्वोत्तम तरीकों का भी पालन करना चाहिए।

यह भी देखें: सर्वोत्तम प्रथाओं की एक अच्छी सूची

मैं जोड़ूंगा, बहुत महत्वपूर्ण, final संशोधक का अच्छा उपयोग करें
जावा में लागू होने पर "अंतिम" संशोधक का उपयोग करना

सारांश:

  1. अच्छे प्रारंभ को लागू करने के लिए final संशोधक का उपयोग करें
  2. विधियों में निरर्थक लौटने से बचें, उदाहरण के लिए, जब लागू हो तो रिक्त संग्रह लौटाए।
  3. एनोटेशन @Nullable और @Nullable उपयोग करें
  4. तेजी से असफल हो और अनावश्यक वस्तुओं के प्रचार से बचने के लिए उपयोग करें, जब वे निरर्थक न हो जाएं।
  5. ज्ञात ऑब्जेक्ट के साथ बराबर का उपयोग करें पहले: if("knownObject".equals(unknownObject)
  6. मूल्य को प्राथमिकता दें valueOf() पर toString ()
  7. रिक्त सुरक्षित StringUtils विधि StringUtils.isEmpty(null) उपयोग करें

NullPointerException एस अपवाद हैं जो तब होते हैं जब आप किसी ऐसे संदर्भ का उपयोग करने का प्रयास करते हैं जो स्मृति (नल) में कोई स्थान नहीं बताती है जैसे कि वह ऑब्जेक्ट को संदर्भित कर रहा था। एक रिक्त संदर्भ पर किसी विधि को कॉल करना या एक रिक्त संदर्भ के क्षेत्र में प्रवेश करने का प्रयास करना एक NullPointerException ट्रिगर करेगा। यह सबसे आम है, लेकिन अन्य तरीके NullPointerException javadoc पृष्ठ पर सूचीबद्ध हैं।

शायद सबसे तेज उदाहरण कोड मैं एक NullPointerException वर्णन के साथ आ सकता है:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

मुख्य के अंदर पहली पंक्ति पर मैं स्पष्ट रूप से Object रेफरेंस obj को null के बराबर सेट कर रहा हूं। इसका मतलब है कि मेरे पास एक संदर्भ है, लेकिन यह किसी वस्तु को इंगित नहीं कर रहा है। उसके बाद, मैं संदर्भ का इलाज करने की कोशिश करता हूं, यद्यपि वह किसी वस्तु को उस पर एक विधि को बुलाता है। यह एक NullPointerException में परिणाम है क्योंकि उस स्थान में निष्पादित करने के लिए कोई कोड नहीं है जो संदर्भ इंगित कर रहा है।

(यह एक तकनीकी है, लेकिन मुझे लगता है कि यह उल्लेख करना जारी रखता है: एक संदर्भ जो अशक्त करने के लिए इंगित करता है, वह एक सी पॉइंटर के समान नहीं है जो कि एक अमान्य स्मृति स्थान को इंगित करता है। एक अशक्त सूचक शाब्दिक रूप से कहीं भी इंगित नहीं है , जो कि अलग से अलग है उस स्थान की ओर इशारा करते हैं जो अमान्य हो।)


नल सूचक अपवाद तब फेंका जाता है जब कोई एप्लिकेशन किसी ऐसे मामले में शून्य का उपयोग करने का प्रयास करता है जहां कोई वस्तु आवश्यक है। इसमें शामिल है:

  1. null ऑब्जेक्ट की आवृत्ति विधि को कॉल करना।
  2. किसी null वस्तु के क्षेत्र में प्रवेश करना या संशोधित करना।
  3. null की लंबाई लेना जैसे कि यह एक सरणी थी
  4. null की स्लॉट्स तक पहुंच या संशोधित करना जैसे कि यह एक सरणी है
  5. null तरह फेंकना जैसे वह एक थ्रोहेबल वैल्यू थे।

null वस्तु के अन्य गैरकानूनी उपयोगों को इंगित करने के लिए आवेदनों को इस वर्ग के उदाहरणों को फेंकना चाहिए।

संदर्भ: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html






nullpointerexception