java - किसी को Objects.requireNonNull() का उपयोग क्यों करना चाहिए?




java-8 nullpointerexception (4)

मैंने नोट किया है कि Oracle JDK में कई जावा 8 तरीके Objects.requireNonNull() उपयोग करते हैं, जो कि दिए गए ऑब्जेक्ट (तर्क) के null NullPointerException आंतरिक रूप से फेंकता है।

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

लेकिन NullPointerException को वैसे भी फेंक दिया जाएगा अगर कोई null वस्तु dereferenced है। तो, किसी को यह अतिरिक्त अशक्त जांच क्यों करनी चाहिए और NullPointerException फेंक देना चाहिए?

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


लेकिन NullPointerException को वैसे भी फेंक दिया जाएगा अगर कोई अशक्त वस्तु dereferenced है। तो, किसी को यह अतिरिक्त अशक्त जांच क्यों करनी चाहिए और NullPointerException को फेंक देना चाहिए?

इसका मतलब है कि आप समस्या का तुरंत और मज़बूती से पता लगा सकते हैं।

विचार करें:

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

.NET ने ArgumentNullException से NullReferenceException ("आपने एक अशक्त मान") को अलग करके इसे बेहतर बनाया है ("आपको एक तर्क के रूप में अशक्त में पारित नहीं होना चाहिए था - और यह इस पैरामीटर के लिए था)। काश जावा भी यही काम करता, लेकिन। यहां तक ​​कि सिर्फ एक NullPointerException , कोड को ठीक करना अभी भी बहुत आसान है यदि त्रुटि को उस शुरुआती बिंदु पर फेंक दिया जाता है जिस पर यह पता लगाया जा सकता है।


विफल फास्ट

कोड जितनी जल्दी हो सके दुर्घटनाग्रस्त हो जाना चाहिए। यह काम का आधा हिस्सा नहीं करना चाहिए और फिर अशक्तता और दुर्घटना को रोकना चाहिए, तभी कुछ काम पूरा हो जाएगा, जिससे सिस्टम अमान्य स्थिति में हो सकता है।

इसे आमतौर पर "असफल जल्दी" या en.wikipedia.org/wiki/Fail-fast


एक साइड नोट के रूप में, Object#requireNotNull से पहले यह तेजी से विफल हो जाता है Object#requireNotNull को जावा -9 से पहले कुछ अलग-अलग वर्गों में खुद को लागू किया गया था। मान लीजिए मामला:

 Consumer<String> consumer = System.out::println;

जावा -8 में यह (केवल प्रासंगिक भागों के रूप में) संकलित है

getstatic Field java/lang/System.out
invokevirtual java/lang/Object.getClass

मूल रूप से एक ऑपरेशन के रूप में: yourReference.getClass - जो कि विफल हो जाएगा यदि आपका आरफेरेंस null

Jdk-9 में चीजें बदल गई हैं जहां समान कोड संकलन करता है

getstatic Field java/lang/System.out
invokestatic java/util/Objects.requireNonNull

या मूल रूप से Objects.requireNotNull (yourReference)


क्योंकि आप ऐसा करके चीजों को स्पष्ट कर सकते हैं। पसंद:

public class Foo {
  private final Bar bar;

  public Foo(Bar bar) {
    Objects.requireNonNull(bar, "bar must not be null");
    this.bar = bar;
  }

या कम:

  this.bar = Objects.requireNonNull(bar, "bar must not be null");

अब आप जानते हैं :

  • जब Foo ऑब्जेक्ट को new() का उपयोग करके सफलतापूर्वक बनाया गया था
  • फिर इसके बार क्षेत्र को गैर-शून्य होने की गारंटी दी जाती है।

उस से तुलना करें: आप आज एक फू ऑब्जेक्ट बनाते हैं, और कल आप उस विधि का उपयोग करते हैं जो उस फ़ील्ड का उपयोग करता है और फेंकता है। सबसे अधिक संभावना है, आप कल नहीं जान पाएंगे कि कल यह संदर्भ शून्य क्यों था जब यह कंस्ट्रक्टर को पारित कर दिया गया था!

दूसरे शब्दों में: आने वाले संदर्भों की जांच करने के लिए स्पष्ट रूप से इस पद्धति का उपयोग करके आप उस समय बिंदु को नियंत्रित कर सकते हैं जब अपवाद फेंक दिया जाएगा। और ज्यादातर समय, आप जितनी जल्दी हो सके असफल होना चाहते हैं !

प्रमुख लाभ हैं:

  • जैसा कि कहा गया है, नियंत्रित व्यवहार
  • आसान डीबगिंग - क्योंकि आप ऑब्जेक्ट निर्माण के संदर्भ में फेंक देते हैं। ऐसे समय में जहां आपके पास एक निश्चित मौका है कि आपके लॉग / निशान आपको बताएं कि क्या गलत हुआ!
  • और जैसा कि ऊपर दिखाया गया है: इस विचार की सच्ची शक्ति अंतिम क्षेत्रों के साथ मेल खाती है। क्योंकि अब आपकी कक्षा का कोई भी अन्य कोड सुरक्षित रूप से यह मान सकता है कि bar शून्य नहीं है - और इस प्रकार आपको अन्य स्थानों में किसी भी तरह की if (bar == null) जाँच की आवश्यकता नहीं है!





nullpointerexception