requireNonNull()एक विधि में पहले कथनों के रूप में उपयोग करने से अभी पहचान करने की अनुमति मिलती है।
स्टैकट्रेस स्पष्ट रूप से इंगित करता है कि अपवाद को विधि के प्रवेश के रूप में जल्द ही फेंक दिया गया था क्योंकि कॉलर आवश्यकताओं / अनुबंध का सम्मान नहीं करता था। nullकिसी अन्य विधि से किसी वस्तु को
पास करना वास्तव में एक समय में एक अपवाद को उत्तेजित कर सकता है लेकिन समस्या का कारण समझने के लिए अधिक जटिल हो सकता है क्योंकि अपवाद को उस nullवस्तु पर एक विशिष्ट आह्वान में फेंक दिया जाएगा जो बहुत आगे हो सकता है।
यहां एक ठोस और वास्तविक उदाहरण है, जो बताता है कि क्यों हमें सामान्य रूप से तेजी से विफल होने और अधिक विशेष रूप से उपयोग Object.requireNonNull()करने के लिए या किसी भी तरह से नहीं होने वाले मापदंडों पर कोई अशक्त जांच करने के लिए किसी भी तरह से विफल होना पड़ता है null।
मान लीजिए कि एक Dictionaryवर्ग जो रचना करता है LookupServiceऔर इसमें निहित शब्दों Listका Stringप्रतिनिधित्व करता है। इन क्षेत्रों को डिज़ाइन नहीं किया गया है nullऔर इनमें से एक को Dictionary निर्माणकर्ता में पारित किया गया है ।
अब मान लें कि विधि प्रविष्टि (यहां निर्माणकर्ता है) में Dictionaryबिना nullजांच के "खराब" कार्यान्वयन :
public class Dictionary {
private final List<String> words;
private final LookupService lookupService;
public Dictionary(List<String> words) {
this.words = this.words;
this.lookupService = new LookupService(words);
}
public boolean isFirstElement(String userData) {
return lookupService.isFirstElement(userData);
}
}
public class LookupService {
List<String> words;
public LookupService(List<String> words) {
this.words = words;
}
public boolean isFirstElement(String userData) {
return words.get(0).contains(userData);
}
}
अब, पैरामीटर के लिए संदर्भ के Dictionaryसाथ निर्माता को आमंत्रित करें :nullwords
Dictionary dictionary = new Dictionary(null);
// exception thrown lately : only in the next statement
boolean isFirstElement = dictionary.isFirstElement("anyThing");
JVM ने इस कथन पर NPE फेंका:
return words.get(0).contains(userData);
थ्रेड में अपवाद "मुख्य" java.lang.NullPointerException
LookupService.isFirstElement (LookupService.java) पर
Dictionary.isFirstElement (Dictionary.java:15) पर
Dictionary.main पर (Dictionary.java:22)
अपवाद LookupServiceकक्षा में शुरू हो जाता है जबकि इसका मूल पहले ( Dictionaryनिर्माणकर्ता) है। यह समग्र मुद्दे के विश्लेषण को बहुत कम स्पष्ट करता है।
है words null? है words.get(0) null? दोनों? क्यों एक, दूसरे या शायद दोनों हैं null? क्या यह Dictionary(निर्माणकर्ता? आह्वान विधि?) में एक कोडिंग त्रुटि है ? क्या यह एक कोडिंग त्रुटि है LookupService? (कंस्ट्रक्टर? चालान विधि?)
अंत में, हमें त्रुटि मूल को खोजने के लिए अधिक कोड का निरीक्षण करना होगा और एक अधिक जटिल वर्ग में शायद डिबगर का उपयोग करने के लिए और अधिक आसानी से समझने के लिए कि यह क्या हुआ।
लेकिन एक साधारण बात (शून्य जांच की कमी) एक जटिल मुद्दा क्यों बन जाती है?
क्योंकि हमने निचले घटकों पर एक विशिष्ट घटक रिसाव पर प्रारंभिक बग / अभाव पहचान की अनुमति दी थी।
कल्पना करें कि LookupServiceकुछ डिबगिंग जानकारी के साथ एक स्थानीय सेवा नहीं बल्कि एक दूरस्थ सेवा या एक थर्ड पार्टी लाइब्रेरी थी या कल्पना करें कि आपके पास 2 परतें नहीं थीं लेकिन इससे पहले कि वस्तु का 4 या 5 परतों पर आक्रमण nullहो? समस्या का विश्लेषण करने के लिए अभी भी अधिक जटिल होगा।
तो एहसान करने का तरीका है:
public Dictionary(List<String> words) {
this.words = Objects.requireNonNull(words);
this.lookupService = new LookupService(words);
}
इस तरह से, कोई सिरदर्द नहीं: जैसे ही यह प्राप्त होता है, हमें अपवाद फेंक दिया जाता है:
// exception thrown early : in the constructor
Dictionary dictionary = new Dictionary(null);
// we never arrive here
boolean isFirstElement = dictionary.isFirstElement("anyThing");
थ्रेड में अपवाद "मुख्य" java.lang.NullPointerException
java.util.Objects.requireNonNull (Objects.java:203) पर
com.Dictionary पर। (Dictionary.java:15)
com.Dictionary.main पर (Dictionary.java:24)
ध्यान दें कि यहाँ मैंने एक निर्माता के साथ समस्या का वर्णन किया था, लेकिन एक विधि आह्वान में एक ही गैर-शून्य चेक बाधा हो सकती है।