नल चेक चेन बनाम पकड़ने वाला NullPointerException


118

एक वेब सेवा एक बहुत बड़ा XML लौटाती है और मुझे इसके बारे में गहराई से नेस्टेड खेतों तक पहुँचने की आवश्यकता है। उदाहरण के लिए:

return wsObject.getFoo().getBar().getBaz().getInt()

समस्या यह है कि है getFoo(), getBar(), getBaz()सब वापस आ सकते हैं null

हालांकि, अगर मैं nullसभी मामलों में जांच करता हूं, तो कोड बहुत ही क्रियात्मक और पढ़ने में कठिन हो जाता है। इसके अलावा, मुझे कुछ क्षेत्रों के लिए चेक याद आ सकते हैं।

if (wsObject.getFoo() == null) return -1;
if (wsObject.getFoo().getBar() == null) return -1;
// maybe also do something with wsObject.getFoo().getBar()
if (wsObject.getFoo().getBar().getBaz() == null) return -1;
return wsObject.getFoo().getBar().getBaz().getInt();

क्या लिखना स्वीकार्य है?

try {
    return wsObject.getFoo().getBar().getBaz().getInt();
} catch (NullPointerException ignored) {
    return -1;
}

या जिसे एक एंटीपार्टर्न माना जाएगा?


29
मुझे nullलगता है कि wsObject.getFoo().getBar().getBaz().getInt()पहले से ही एक कोड गंध के बाद से, बहुत बुरा नहीं होगा । पढ़ें कि "लॉ ​​ऑफ़ डेमेटर" क्या है और तदनुसार अपने कोड को फिर से भरना पसंद करें। फिर nullचेक के साथ समस्या भी दूर हो जाएगी। और उपयोग करने के बारे में सोचें Optional
टॉम

9
XPath का उपयोग करने और उनके मूल्यांकन पर छोड़ने के बारे में क्या ?
जोप इगेन

15
यह कोड संभवतः जनरेट किया गया है wsdl2java, जिसमें लॉ ऑफ डेमिटर के लिए कोई सम्मान नहीं है।
एड्रियन कॉक्स

जवाबों:


143

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

मेरा सुझाव है कि आप Optionalइसके बजाय कक्षा का उपयोग करें । जब आप वर्तमान या अनुपस्थित मानों के साथ काम करना चाहते हैं, तो यह अक्सर सबसे अच्छा तरीका होता है।

इसका उपयोग करके आप अपना कोड इस तरह लिख सकते हैं:

public Optional<Integer> m(Ws wsObject) {
    return Optional.ofNullable(wsObject.getFoo()) // Here you get Optional.empty() if the Foo is null
        .map(f -> f.getBar()) // Here you transform the optional or get empty if the Bar is null
        .map(b -> b.getBaz())
        .map(b -> b.getInt());
        // Add this if you want to return null instead of an empty optional if any is null
        // .orElse(null);
        // Or this if you want to throw an exception instead
        // .orElseThrow(SomeApplicationException::new);
}

वैकल्पिक क्यों?

अनुपस्थित मानों के Optionalबजाय s का उपयोग करना, nullउस तथ्य को पाठकों के लिए बहुत ही दृश्यमान और स्पष्ट बनाता है, और टाइप सिस्टम यह सुनिश्चित करेगा कि आप गलती से इसके बारे में भूल न जाएं।

आप इस तरह के मूल्यों के साथ काम करने के तरीकों तक पहुंच प्राप्त करते हैं, जैसे कि अधिक सुविधाजनक, जैसे mapऔर orElse


अनुपस्थिति वैध है या त्रुटि?

लेकिन यह भी सोचें कि क्या यह मध्यवर्ती तरीकों के लिए अशक्त होने के लिए एक वैध परिणाम है या यदि यह एक त्रुटि का संकेत है। यदि यह हमेशा एक त्रुटि है, तो एक विशेष मूल्य को वापस करने की तुलना में शायद एक अपवाद को फेंकना बेहतर है, या खुद को एक अपवाद फेंकने के लिए मध्यवर्ती तरीकों के लिए।


शायद अधिक वैकल्पिक?

यदि दूसरी ओर मध्यवर्ती विधियों से अनुपस्थित मान मान्य हैं, तो शायद आप Optionalउनके लिए भी स्विच कर सकते हैं?

तब आप उन्हें इस तरह इस्तेमाल कर सकते हैं:

public Optional<Integer> mo(Ws wsObject) {
    return wsObject.getFoo()
        .flatMap(f -> f.getBar())
        .flatMap(b -> b.getBaz())
        .flatMap(b -> b.getInt());        
}

वैकल्पिक क्यों नहीं?

इसका उपयोग न करने के लिए मैं केवल एक ही कारण सोच सकता हूं कि Optionalक्या यह कोड के वास्तव में प्रदर्शन के महत्वपूर्ण हिस्से में है, और यदि कचरा संग्रह ओवरहेड एक समस्या बन जाता है। इसका कारण यह है कुछ है Optionalवस्तुओं हर बार कोड निष्पादित होने पर आवंटित किए जाते हैं, और वीएम सकता है उन दूर अनुकूलन करने के लिए सक्षम नहीं हो। उस मामले में आपके मूल यदि परीक्षण बेहतर हो सकते हैं।


बहुत अच्छा जवाब। यह उल्लेख किया जाना चाहिए कि यदि अन्य संभावित विफलता की स्थिति है, और आपको उनके बीच अंतर करने की आवश्यकता है, तो आप Tryइसके बजाय उपयोग कर सकते हैं Optional। हालाँकि Try, जावा एपीआई में कोई भी नहीं है, लेकिन एक प्रदान करने वाले कई कार्य हैं , जैसे javaslang.io , github.com/bradleyscollins/try4j , functionaljava.org या github.com/jasongoodwin
-better

8
FClass::getBarआदि छोटा होगा।
बोरिस स्पाइडर

1
@ बोरिशाइपर: शायद थोड़ा सा। लेकिन मैं आमतौर पर लैम्बदास को पसंद करता हूं, क्योंकि विधि के नाम बहुत अधिक लंबे हैं, और मुझे लैम्ब्डा पढ़ने में थोड़ी आसान लगती है।
Lii

6
@Lii काफी उचित है, लेकिन ध्यान दें कि एक विधि संदर्भ एक छोटे से तेजी से हो सकता है, क्योंकि एक लंबोदर को अधिक जटिल संकलन निर्माण की आवश्यकता हो सकती है। लैम्ब्डा को एक staticविधि की पीढ़ी की आवश्यकता होगी , जो बहुत मामूली जुर्माना लगाएगा।
बोरिस द स्पाइडर

1
@ एलआईआई मैं वास्तव में क्लीनर और अधिक वर्णनात्मक होने के लिए विधि संदर्भ ढूंढता है, भले ही वे थोड़े लंबे समय तक हों।
शमोसल

14

मैं विचार करने का सुझाव देता हूं Objects.requireNonNull(T obj, String message)। आप प्रत्येक अपवाद के लिए एक विस्तृत संदेश के साथ श्रृंखला बना सकते हैं, जैसे

requireNonNull(requireNonNull(requireNonNull(
    wsObject, "wsObject is null")
        .getFoo(), "getFoo() is null")
            .getBar(), "getBar() is null");

मैं आपको सुझाव दूंगा कि आप विशेष रिटर्न-वैल्यूज़ का उपयोग न करें, जैसे -1। यह एक जावा शैली नहीं है। जावा ने इस पुराने ढंग से बचने के लिए अपवादों का तंत्र तैयार किया है जो C भाषा से आया है।

फेंकना NullPointerExceptionभी सबसे अच्छा विकल्प नहीं है। आप अपना स्वयं का अपवाद प्रदान कर सकते हैं (यह सुनिश्चित करने के लिए जाँच की जा सकती है कि इसे उपयोगकर्ता द्वारा नियंत्रित किया जाएगा या इसे आसान तरीके से संसाधित करने के लिए अनियंत्रित किया जाएगा) या आप जिस XML पार्सर का उपयोग कर रहे हैं उससे एक विशिष्ट अपवाद का उपयोग करें।


1
Objects.requireNonNullअंततः फेंकता है NullPointerException। तो यह स्थिति को किसी भी तरह से अलग नहीं बनाता हैreturn wsObject.getFoo().getBar().getBaz().getInt()
अर्का घोष

1
@ArkaGhosh, यह भी बहुत से बचा जाता है ifजैसा कि ओपी ने दिखाया
एंड्रयू टोबिल्को

4
यही एकमात्र समाधान है। अन्य सभी प्रवाह नियंत्रण के लिए अपवाद का उपयोग करने की सलाह देते हैं जो एक कोड गंध है। एक साइड नोट पर: मैं ओपी द्वारा की गई विधि को एक गंध के रूप में अच्छी तरह से समझता हूं। यदि वह तीन स्थानीय चरों के साथ काम करेगा और यदि स्थिति अधिक स्पष्ट होगी तो इसी के साथ। इसके अलावा, मुझे लगता है कि समस्या केवल एनपीई के आसपास काम करने की तुलना में अधिक गहरी है: ओपी को खुद से पूछना चाहिए कि गेटर्स अशक्त क्यों लौट सकते हैं। अशक्त का क्या अर्थ है? शायद कुछ अशक्त वस्तु बेहतर होगी? या सार्थक अपवाद के साथ एक गटर में दुर्घटना? मूल रूप से सब कुछ प्रवाह नियंत्रण के अपवादों से बेहतर है।
मारियस के।

1
वैध रिटर्न मूल्य की अनुपस्थिति को इंगित करने के लिए अपवादों का उपयोग करने की बिना शर्त सलाह बहुत अच्छी नहीं है। अपवाद तब उपयोगी होते हैं जब एक विधि एक तरह से विफल हो जाती है जो कॉल करने वाले से उबरने के लिए कठिन होती है और जिसे कार्यक्रम के किसी अन्य हिस्से में कोशिश-कैच-स्टेटमेंट में बेहतर तरीके से नियंत्रित किया जाता है। केवल वापसी मूल्य की अनुपस्थिति का संकेत देने के लिए Optionalवर्ग का उपयोग करना बेहतर है , या शायद एक अशक्त लौटाने के लिएInteger
Lii

6

यह मानते हुए कि वर्ग संरचना वास्तव में हमारे नियंत्रण से बाहर है, जैसा कि मामला प्रतीत होता है, मुझे लगता है कि एनपीई को पकड़ना जैसा कि प्रश्न में सुझाया गया है वास्तव में एक उचित समाधान है, जब तक कि प्रदर्शन एक प्रमुख चिंता का विषय नहीं है। अव्यवस्था से बचने के लिए थ्रो / कैच लॉजिक को लपेटना एक छोटा सुधार हो सकता है:

static <T> T get(Supplier<T> supplier, T defaultValue) {
    try {
        return supplier.get();
    } catch (NullPointerException e) {
        return defaultValue;
    }
}

अब आप बस कर सकते हैं:

return get(() -> wsObject.getFoo().getBar().getBaz().getInt(), -1);

return get(() -> wsObject.getFoo().getBar().getBaz().getInt(), "");संकलित समय में त्रुटि नहीं देता है जो समस्याग्रस्त हो सकता है।
फिलिप गियोसेफ़ी

5

जैसा कि टॉम ने पहले ही टिप्पणी में कहा था ,

स्टेटमेंट ऑफ डेमेटर की अवज्ञा के बाद ,

wsObject.getFoo().getBar().getBaz().getInt()

आप क्या चाहते हैं intऔर आप इसे प्राप्त कर सकते हैं FooLaw of Demeter कहता है, कभी भी अजनबियों से बात न करें । अपने मामले के लिए आप के कार्यान्वयन को छुपा सकते हैं के हुड के तहत Fooऔर Bar

अब, आप में विधि बना सकते हैं Fooलाने के लिए intसे Baz। अंतत:, Fooहोगा Barऔर Barहम सीधे Intउजागर किए बिना पहुंच सकते हैं । इसलिए, अशक्त जांच को शायद अलग-अलग वर्गों में विभाजित किया जाता है और केवल आवश्यक विशेषताओं को कक्षाओं में साझा किया जाएगा।BazFoo


4
WsObject शायद केवल एक डेटा संरचना है क्योंकि यह डिमेटर के कानून की अवज्ञा करता है, यह बहस का विषय है। यहां देखें: stackoverflow.com/a/26021695/1528880
DerM

2
@DerM हाँ, यह संभव है, लेकिन चूंकि ओपी के पास पहले से ही अपनी XML फ़ाइल होती है, इसलिए वह आवश्यक टैग के लिए उपयुक्त मॉडल कक्षाएं बनाने के बारे में भी सोच सकता है, इसलिए पार्सिंग लाइब्रेरी उन्हें मैप कर सकती है। फिर इन मॉडल कक्षाओं में nullअपने स्वयं के उप टैग की जांच के लिए तर्क होते हैं ।
टॉम

4

मेरा उत्तर लगभग @janki जैसी ही पंक्ति में जाता है, लेकिन मैं नीचे दिए गए कोड स्निपेट को संशोधित करना चाहूंगा:

if (wsObject.getFoo() != null && wsObject.getFoo().getBar() != null && wsObject.getFoo().getBar().getBaz() != null) 
   return wsObject.getFoo().getBar().getBaz().getInt();
else
   return something or throw exception;

आप के wsObjectरूप में अच्छी तरह से के लिए एक अशक्त जाँच जोड़ सकते हैं , अगर उस वस्तु के अशक्त होने का कोई मौका है।


4

आप कहते हैं कि कुछ तरीके "वापस लौट सकते हैं null" लेकिन यह नहीं कहते कि वे किन परिस्थितियों में लौटते हैं null। आप कहते हैं कि आप पकड़ते हैं NullPointerExceptionलेकिन आप यह नहीं कहते कि आप इसे क्यों पकड़ते हैं। जानकारी की कमी से आपको पता चलता है कि आपको इस बात की स्पष्ट समझ नहीं है कि अपवाद क्या हैं और वे विकल्प से बेहतर क्यों हैं।

एक वर्ग विधि पर विचार करें जो किसी क्रिया को करने के लिए है, लेकिन विधि इसकी गारंटी नहीं दे सकती है कि वह क्रिया को निष्पादित करेगी, क्योंकि इसके नियंत्रण से परे परिस्थितियों (जो वास्तव में जावा में सभी विधियों के लिए मामला है )। हम उस तरीके को कहते हैं और यह वापस लौटता है। उस पद्धति को कॉल करने वाले कोड को यह जानना होगा कि क्या वह सफल था। इसे कैसे जान सकते हैं? सफलता या विफलता की दो संभावनाओं से निपटने के लिए इसे कैसे संरचित किया जा सकता है?

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

तो, वे विधियाँ जो वापस आती हैं null

  • क्या कोई nullमान आपके कोड में बग को दर्शाता है? यदि ऐसा होता है, तो आपको अपवाद बिल्कुल नहीं पकड़ना चाहिए। और आपका कोड स्वयं दूसरे अनुमान लगाने का प्रयास नहीं करना चाहिए। बस वही लिखें जो स्पष्ट है और इस धारणा पर संक्षिप्त है कि यह काम करेगा। क्या विधि कॉल स्पष्ट और संक्षिप्त है? तो बस उनका उपयोग करें।
  • क्या कोई nullमान आपके प्रोग्राम में अमान्य इनपुट दर्शाता है? यदि ऐसा होता है, तो NullPointerExceptionफेंकने के लिए एक उपयुक्त अपवाद नहीं है, क्योंकि परंपरागत रूप से यह कीड़े को इंगित करने के लिए आरक्षित है। आप शायद IllegalArgumentException(यदि आप एक अनियंत्रित अपवाद चाहते हैं ) या IOException(यदि आप एक अपवादित अपवाद चाहते हैं ) से प्राप्त कस्टम अपवाद को फेंकना चाहते हैं। क्या अवैध इनपुट होने पर विस्तृत सिंटैक्स त्रुटि संदेश प्रदान करने के लिए आपके प्रोग्राम की आवश्यकता है? यदि ऐसा है, तो nullवापसी मूल्य के लिए प्रत्येक विधि की जाँच करें तो एक उपयुक्त नैदानिक ​​अपवाद फेंकना केवल एक चीज है जो आप कर सकते हैं। यदि आपके प्रोग्राम को विस्तृत डायग्नोस्टिक्स प्रदान करने की आवश्यकता नहीं है, तो विधि कॉल को एक साथ जोड़कर, किसी भी को पकड़ने NullPointerExceptionऔर फिर अपने कस्टम अपवाद को फेंकना सबसे स्पष्ट और सबसे संक्षिप्त है।

उत्तरों में से एक का दावा है कि जंजीर पद्धति कॉल कानून के कानून का उल्लंघन करती है और इस तरह खराब होती है। यह दावा गलत है।

  • जब प्रोग्राम डिज़ाइन की बात आती है, तो वास्तव में कोई भी पूर्ण नियम नहीं हैं कि क्या अच्छा है और क्या बुरा है। केवल अनुमान हैं: नियम जो उस समय के बहुत अधिक (यहां तक ​​कि लगभग सभी) सही हैं। प्रोग्रामिंग के कौशल का एक हिस्सा यह जानता है कि उन प्रकार के नियमों को तोड़ना कब ठीक है। तो एक जोरदार दावा है कि "यह नियम एक्स के खिलाफ है " वास्तव में बिल्कुल भी जवाब नहीं है। क्या यह उन स्थितियों में से एक है जहां नियम को तोड़ा जाना चाहिए?
  • Demeter के कानून वास्तव में एपीआई या वर्ग इंटरफेस डिजाइन के बारे में नियम है। कक्षाओं को डिजाइन करते समय, सार का एक पदानुक्रम होना उपयोगी होता है। आपके पास निम्न स्तर की कक्षाएं हैं जो भाषा प्राइमेटिव का उपयोग सीधे संचालन करने के लिए करती हैं और एक एब्सट्रैक्शन में वस्तुओं का प्रतिनिधित्व करती हैं जो भाषा प्राइमेटिक्स की तुलना में उच्च स्तर है। आपके पास मध्यम स्तर की कक्षाएं हैं जो निम्न स्तर की कक्षाओं को सौंपती हैं, और निम्न स्तर की कक्षाओं की तुलना में उच्च स्तर पर संचालन और प्रतिनिधित्व को लागू करती हैं। आपके पास उच्च स्तरीय कक्षाएं हैं जो मध्यम स्तर की कक्षाओं को सौंपती हैं, और अभी भी उच्च स्तर के संचालन और अमूर्त को लागू करती हैं। (मैंने यहां केवल तीन स्तरों के अमूर्त के बारे में बात की है, लेकिन अधिक संभव है)। यह आपके कोड को प्रत्येक स्तर पर उपयुक्त सार के संदर्भ में खुद को व्यक्त करने की अनुमति देता है, जिससे जटिलता छिपती है। कानून के लिए तर्कक्या यह है कि यदि आपके पास विधि कॉल की एक श्रृंखला है, जो यह बताती है कि आपके पास निम्न स्तर के विवरणों से सीधे निपटने के लिए एक मध्यम स्तर की कक्षा के माध्यम से एक उच्च स्तरीय वर्ग तक पहुँच है, और इसलिए कि आपके मध्यम स्तर के वर्ग ने मध्यम-स्तर का सार संचालन प्रदान नहीं किया है उच्च स्तर की जरूरत है। लेकिन ऐसा लगता है कि आपके पास यहां ऐसी स्थिति नहीं है: आपने कक्षाओं को विधि कॉल की श्रृंखला में डिज़ाइन नहीं किया है, वे कुछ ऑटो-जेनरेट किए गए XML सीरियल कोड (दाएं?) का परिणाम हैं, और कॉल की श्रृंखला अवरोही नहीं है? एक अमूर्त पदानुक्रम के माध्यम से क्योंकि डेस-धारावाहिक एक्सएमएल अमूर्त पदानुक्रम (दाएं?) के समान स्तर पर है?

3

पठनीयता में सुधार करने के लिए, आप कई चर का उपयोग करना चाह सकते हैं, जैसे

Foo theFoo;
Bar theBar;
Baz theBaz;

theFoo = wsObject.getFoo();

if ( theFoo == null ) {
  // Exit.
}

theBar = theFoo.getBar();

if ( theBar == null ) {
  // Exit.
}

theBaz = theBar.getBaz();

if ( theBaz == null ) {
  // Exit.
}

return theBaz.getInt();

यह मेरी राय में बहुत कम पठनीय है। यह अशक्त-जाँच तर्क के पूरे समूह के साथ विधि को प्रस्तुत करता है जो विधि के वास्तविक तर्क से पूरी तरह अप्रासंगिक है।
डेवलपर

2

पकड़ नहीं है NullPointerException। आप नहीं जानते कि यह कहां से आ रहा है (मुझे पता है कि यह आपके मामले में संभावित नहीं है, लेकिन शायद कुछ और इसे फेंक दिया है) और यह धीमा है। आप निर्दिष्ट फ़ील्ड का उपयोग करना चाहते हैं और इसके लिए हर दूसरे क्षेत्र को शून्य नहीं होना चाहिए। यह हर क्षेत्र की जाँच करने का एक सही वैध कारण है। मैं शायद एक में इसकी जांच करूंगा और अगर पठनीयता के लिए कोई तरीका बनाऊंगा। जैसा कि अन्य लोगों ने बताया है कि -1 पहले से ही लौट रहा है, लेकिन वह बहुत कम उम्र का है, लेकिन मुझे नहीं पता कि आपके पास इसका कोई कारण है या नहीं (जैसे किसी अन्य सिस्टम से बात करना)।

public int callService() {
    ...
    if(isValid(wsObject)){
        return wsObject.getFoo().getBar().getBaz().getInt();
    }
    return -1;
}


public boolean isValid(WsObject wsObject) {
    if(wsObject.getFoo() != null &&
        wsObject.getFoo().getBar() != null &&
        wsObject.getFoo().getBar().getBaz() != null) {
        return true;
    }
    return false;
}

संपादित करें: अगर यह WsObject शायद केवल एक डेटा संरचना है (तो https://stackoverflow.com/a/26021695/1528880 की जाँच करें ) के बाद से यह कानून की अवज्ञा करता है, तो यह बहस का मुद्दा है ।


2

यदि आप कोड को रिफलेक्टर नहीं करना चाहते हैं और आप जावा 8 का उपयोग कर सकते हैं, तो विधि संदर्भों का उपयोग करना संभव है।

पहले एक साधारण डेमो (स्थिर आंतरिक कक्षाओं का बहाना)

public class JavaApplication14 
{
    static class Baz
    {
        private final int _int;
        public Baz(int value){ _int = value; }
        public int getInt(){ return _int; }
    }
    static class Bar
    {
        private final Baz _baz;
        public Bar(Baz baz){ _baz = baz; }
        public Baz getBar(){ return _baz; }   
    }
    static class Foo
    {
        private final Bar _bar;
        public Foo(Bar bar){ _bar = bar; }
        public Bar getBar(){ return _bar; }   
    }
    static class WSObject
    {
        private final Foo _foo;
        public WSObject(Foo foo){ _foo = foo; }
        public Foo getFoo(){ return _foo; }
    }
    interface Getter<T, R>
    {
        R get(T value);
    }

    static class GetterResult<R>
    {
        public R result;
        public int lastIndex;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
    {
        WSObject wsObject = new WSObject(new Foo(new Bar(new Baz(241))));
        WSObject wsObjectNull = new WSObject(new Foo(null));

        GetterResult<Integer> intResult
                = getterChain(wsObject, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);

        GetterResult<Integer> intResult2
                = getterChain(wsObjectNull, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);


        System.out.println(intResult.result);
        System.out.println(intResult.lastIndex);

        System.out.println();
        System.out.println(intResult2.result);
        System.out.println(intResult2.lastIndex);

        // TODO code application logic here
    }

    public static <R, V1, V2, V3, V4> GetterResult<R>
            getterChain(V1 value, Getter<V1, V2> g1, Getter<V2, V3> g2, Getter<V3, V4> g3, Getter<V4, R> g4)
            {
                GetterResult result = new GetterResult<>();

                Object tmp = value;


                if (tmp == null)
                    return result;
                tmp = g1.get((V1)tmp);
                result.lastIndex++;


                if (tmp == null)
                    return result;
                tmp = g2.get((V2)tmp);
                result.lastIndex++;

                if (tmp == null)
                    return result;
                tmp = g3.get((V3)tmp);
                result.lastIndex++;

                if (tmp == null)
                    return result;
                tmp = g4.get((V4)tmp);
                result.lastIndex++;


                result.result = (R)tmp;

                return result;
            }
}

उत्पादन

२४१

अशक्त

इंटरफ़ेस Getterसिर्फ एक कार्यात्मक इंटरफ़ेस है, आप किसी भी समकक्ष का उपयोग कर सकते हैं।
GetterResultवर्ग, अभिगमकर्ताओं ने स्पष्टता के लिए छीन लिया, गेटर श्रृंखला के परिणाम को पकड़ें, यदि कोई हो, या अंतिम गेटर के सूचकांक को बुलाया जाए।

विधि getterChainकोड का एक सरल, बॉयलरप्लेट टुकड़ा है, जो स्वचालित रूप से (या मैन्युअल रूप से आवश्यक होने पर) उत्पन्न किया जा सकता है।
मैंने कोड को संरचित किया है ताकि दोहराए जाने वाला ब्लॉक स्वयं स्पष्ट हो।


यह एक सही समाधान नहीं है क्योंकि आपको अभी भी getterChainप्रति गेटर्स की संख्या के एक अधिभार को परिभाषित करने की आवश्यकता है ।

मैं इसके बजाय कोड को रिफलेक्टर करूंगा, लेकिन अगर आप लंबे गेट्टर चेन का उपयोग करके अपने आप को नहीं पा सकते हैं, तो आप अक्सर ओवरलोड के साथ एक क्लास बनाने पर विचार कर सकते हैं, जो कि 2, 10, गेटर्स से लेते हैं।


2

जैसा कि अन्य लोगों ने कहा है, कानून के कानून का सम्मान करना निश्चित रूप से समाधान का हिस्सा है। एक और हिस्सा, जहां भी संभव हो, उन जंजीर विधियों को बदलना है ताकि वे वापस नहीं आ सकें null। आप nullखाली String, खाली Collection, या किसी अन्य डमी ऑब्जेक्ट को वापस करने के बजाय वापस जाने से बच सकते हैं , जिसका अर्थ है कि कॉलर जो भी करेगा या करेगा null


2

मैं एक उत्तर जोड़ना चाहूंगा जो त्रुटि के अर्थ पर ध्यान केंद्रित करता है । अपने आप में अशक्त अपवाद कोई अर्थ पूर्ण त्रुटि प्रदान नहीं करता है। इसलिए मैं उनसे सीधे निपटने से बचने की सलाह दूंगा।

ऐसे हजारों मामले हैं जहां आपका कोड गलत हो सकता है: डेटाबेस, IO अपवाद, नेटवर्क त्रुटि से कनेक्ट नहीं किया जा सकता है ... यदि आप एक-एक करके उनके साथ व्यवहार करते हैं (जैसे यहां नल चेक), तो यह बहुत अधिक परेशानी होगी।

कोड में:

wsObject.getFoo().getBar().getBaz().getInt();

यहां तक ​​कि जब आप जानते हैं कि कौन सा क्षेत्र अशक्त है, तो आपको कुछ भी पता नहीं है कि क्या गलत है। शायद बार अशक्त है, लेकिन क्या यह अपेक्षित है? या यह एक डेटा त्रुटि है? उन लोगों के बारे में सोचें जो आपका कोड पढ़ते हैं

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

कोड फिर से लिखा जा सकता है:

void myFunction()
{
    try 
    {
        if (wsObject.getFoo() == null)
        {
          throw new FooNotExistException();
        }

        return wsObject.getFoo().getBar().getBaz().getInt();
    }
    catch (Exception ex)
    {
        log.error(ex.Message, ex); // Write log to track whatever exception happening
        throw new OperationFailedException("The requested operation failed")
    }
}


void Main()
{
    try
    {
        myFunction();
    }
    catch(FooNotExistException)
    {
        // Show error: "Your foo does not exist, please check"
    }
    catch(OperationFailedException)
    {
        // Show error: "Operation failed, please contact our support"
    }
}

अनियंत्रित अपवाद इंगित करते हैं कि प्रोग्रामर एपीआई का दुरुपयोग कर रहा है। बाहरी समस्याओं जैसे "डेटाबेस से कनेक्ट नहीं किया जा सकता है, IO अपवाद, नेटवर्क त्रुटि" चेक अपवादों द्वारा इंगित किया जाना चाहिए।
केविन क्रुमविडे

यह वास्तव में फोन करने वाले की जरूरत पर निर्भर करता है। जाँच अपवाद मदद क्योंकि यह आपको त्रुटि को संसाधित करने के लिए मजबूर करती है। हालाँकि, अन्य मामलों में, यह आवश्यक नहीं है और कोड को प्रदूषित कर सकता है। उदाहरण के लिए, आपकी डेटा लेयर में IOException है, तो क्या आप इसे प्रेजेंटेशन लेयर पर फेंकेंगे? इसका मतलब है कि आपको हर कॉलर पर अपवाद को पकड़ना होगा और फिर से फेंकना होगा। मैं एक प्रासंगिक संदेश के साथ एक कस्टम BusinessException द्वारा IOException को लपेटना पसंद करता हूं, और स्टैकट्रेस के माध्यम से इसे पॉप करने देता हूं, जब तक कि एक वैश्विक फ़िल्टर इसे पकड़कर उपयोगकर्ता को संदेश प्रदर्शित नहीं करता।
होन्गे लांग

कॉलर को चेक किए गए अपवादों को पकड़ने और फिर से फेंकने की ज़रूरत नहीं है, बस उन्हें फेंकने की घोषणा करें।
केविन क्रुमिडेव जुई

@KevinKrumwiede: आप सही हैं, हमें केवल फेंके जाने वाले अपवाद को घोषित करने की आवश्यकता है। हमें अभी भी घोषित करने की आवश्यकता है। संपादित करें: इस पर दूसरा नज़र डालें, तो जाँच बनाम अनियोजित अपवाद usages के बारे में बहुत बहसें होती हैं (जैसे: programmers.stackexchange.com/questions/121328/… )।
लॉन्ग

2

NullPointerException एक रन-टाइम अपवाद है, इसलिए आम तौर पर इसे पकड़ने के लिए बोलने की सिफारिश नहीं की जाती है, लेकिन इससे बचने के लिए।

आप जहां भी विधि को कॉल करना चाहते हैं (या यह स्टैक को प्रचारित करेगा) आपको अपवाद को पकड़ना होगा। फिर भी, अगर आपके मामले में आप मान -1 के साथ उस परिणाम के साथ काम कर सकते हैं और आप सुनिश्चित हैं कि यह प्रचार नहीं करेगा क्योंकि आप "टुकड़े" में से किसी का उपयोग नहीं कर रहे हैं जो अशक्त हो सकता है, तो यह मेरे लिए सही लगता है पकड़ लो

संपादित करें:

मैं @xenteros से बाद के उत्तर से सहमत हूं , यह -1 को वापस करने के बजाय अपने स्वयं के अपवाद को लॉन्च करना बेहतर होगा, आप इसे InvalidXMLExceptionउदाहरण के लिए कह सकते हैं ।


3
"अगर आप इसे पकड़ते हैं तो कोई फर्क नहीं पड़ता" का क्या मतलब है, यह कोड के अन्य भागों में प्रचारित कर सकता है?
हल्क

यदि null इस वाक्य में है wsObject.getFoo () और कोड के बाद के भागों में आप फिर से उस क्वेरी को चलाते हैं या wsObject.getFoo ()। GetBar () (उदाहरण के लिए) का उपयोग करते हैं तो यह फिर से NullPointerException बढ़ाएगा।
स्काउट

यह "आप विधि को कॉल करना चाहते हैं (या यह स्टैक को प्रचारित करेगा) के लिए" आपको अपवाद छोड़ना होगा। अगर मे ठीक समझता हूँ। मैं इससे सहमत हूं (और यह एक समस्या हो सकती है), मैं सिर्फ भ्रमित करने के लिए शब्द ढूंढता हूं।
हल्क

मैं इसे ठीक करूंगा, क्षमा करें, अंग्रेजी मेरी पहली भाषा नहीं है, इसलिए यह कभी-कभी हो सकती है :) धन्यवाद
स्काउट

2

कल से इस पद का अनुसरण कर रहे हैं।

मैं टिप्पणी कर रहा हूं / टिप्पणी कर रहा हूं जो कहता है कि एनपीई को पकड़ना बुरा है। यहाँ मैं ऐसा क्यों कर रहा हूँ।

package com.todelete;

public class Test {
    public static void main(String[] args) {
        Address address = new Address();
        address.setSomeCrap(null);
        Person person = new Person();
        person.setAddress(address);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            try {
                System.out.println(person.getAddress().getSomeCrap().getCrap());
            } catch (NullPointerException npe) {

            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println((endTime - startTime) / 1000F);
        long startTime1 = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            if (person != null) {
                Address address1 = person.getAddress();
                if (address1 != null) {
                    SomeCrap someCrap2 = address1.getSomeCrap();
                    if (someCrap2 != null) {
                        System.out.println(someCrap2.getCrap());
                    }
                }
            }
        }
        long endTime1 = System.currentTimeMillis();
        System.out.println((endTime1 - startTime1) / 1000F);
    }
}

  public class Person {
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

package com.todelete;

public class Address {
    private SomeCrap someCrap;

    public SomeCrap getSomeCrap() {
        return someCrap;
    }

    public void setSomeCrap(SomeCrap someCrap) {
        this.someCrap = someCrap;
    }
}

package com.todelete;

public class SomeCrap {
    private String crap;

    public String getCrap() {
        return crap;
    }

    public void setCrap(String crap) {
        this.crap = crap;
    }
}

उत्पादन

3.216

0.002

मुझे यहां एक स्पष्ट विजेता दिखाई दे रहा है। अगर चेक अपवाद है तो अपवाद पकड़ने की तुलना में बहुत कम महंगा है। मैंने देखा है कि जावा -8 करने का तरीका। यह देखते हुए कि वर्तमान अनुप्रयोगों का 70% अभी भी जावा -7 पर चलता है मैं इस उत्तर को जोड़ रहा हूं।

निचला रेखा किसी भी मिशन के महत्वपूर्ण अनुप्रयोगों के लिए, एनपीई को संभालना महंगा है।


सबसे खराब स्थिति में एक लाख अनुरोधों पर तीन अतिरिक्त सेकंड औसत दर्जे का है, लेकिन यह "मिशन क्रिटिकल क्रिटिकल" में भी शायद ही कोई डील ब्रेकर होगा। ऐसी प्रणालियां हैं जहां अनुरोध में 3.2 माइक्रोसेकंड जोड़ना एक बड़ी बात है, और यदि आपके पास ऐसी प्रणाली है, तो हर तरह से अपवादों के बारे में सावधानी से सोचें। लेकिन एक वेब सेवा को कॉल करना और मूल प्रश्न के अनुसार, इसके आउटपुट को डिसेररलाइज़ करना, शायद इससे बहुत अधिक समय लेता है, और अपवाद बिंदु के प्रदर्शन के बारे में चिंता करना इस बिंदु के बगल में है।
जेरेन मोस्टर्ट

@ JeroenMostert: प्रति चेक 3 मिलियन / मिलियन। तो, चेक की संख्या लागत में वृद्धि करेगी
NewUser

सच। यहां तक ​​कि इसके साथ मैं अभी भी इसे "प्रोफाइल फर्स्ट" का मामला मानूंगा, हालांकि। अनुरोध पूर्ण मिलिसेकंड अतिरिक्त लेने से पहले आपको एक अनुरोध में 300 से अधिक चेक की आवश्यकता होगी। डिजाइन के विचार मेरी आत्मा पर जल्द से जल्द तौलेंगे।
जीरो मोस्टर्ट

@JeroenMostert: :) सहमत! मैं इसे परिणाम के साथ प्रोग्रामर तक छोड़ना चाहूंगा और उन्हें कॉल करने दूंगा!
न्यूसर

1

यदि दक्षता एक मुद्दा है तो 'कैच' विकल्प पर विचार किया जाना चाहिए। यदि 'कैच' का उपयोग नहीं किया जा सकता है क्योंकि यह प्रचार करेगा (जैसा कि 'स्काउटो' द्वारा उल्लेख किया गया है) तो कई तरीकों से कॉल करने से बचने के लिए स्थानीय चर का उपयोग करें getFoo(), getBar()और getBaz()


1

यह अपने स्वयं के अपवाद बनाने पर विचार करने लायक है। चलो इसे MyOperationFailedException कहते हैं। आप एक मान वापस करने के बजाय इसे फेंक सकते हैं। परिणाम समान होगा - आप फ़ंक्शन छोड़ देंगे, लेकिन आप हार्ड-कोडित मान -1 नहीं लौटाएंगे, जो कि जावा एंटी-पैटर्न है। जावा में हम अपवाद का उपयोग करते हैं।

try {
    return wsObject.getFoo().getBar().getBaz().getInt();
} catch (NullPointerException ignored) {
    throw new MyOperationFailedException();
}

संपादित करें:

टिप्पणियों में चर्चा के अनुसार मुझे अपने पिछले विचारों में कुछ जोड़ने दें। इस कोड में दो संभावनाएँ हैं। एक यह है कि आप अशक्त को स्वीकार करते हैं और दूसरा यह है कि यह एक त्रुटि है।

यदि यह एक त्रुटि है और ऐसा होता है, तो आप अपने कोड को डीबगिंग उद्देश्यों के लिए अन्य संरचनाओं का उपयोग करके डिबग कर सकते हैं जब ब्रेकप्वाइंट पर्याप्त नहीं होते हैं।

यदि यह स्वीकार्य है, तो आपको इस बात की परवाह नहीं है कि यह अशक्त कहाँ दिखाई दिया। यदि आप करते हैं, तो आपको निश्चित रूप से उन अनुरोधों को श्रृंखलाबद्ध नहीं करना चाहिए।


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

नहीं, आपके अपवाद में एक संदेश हो सकता है जो निश्चित रूप से उस स्थान को इंगित करेगा जहां उसे फेंक दिया गया था। मैं मानता हूँ कि चेनिंग सबसे अच्छा समाधान नहीं है :)
xenteros

3
नहीं, यह सिर्फ लाइन नंबर के बारे में कहेंगे। इसलिए, श्रृंखला में कोई भी कॉल अपवाद हो सकती है।
न्यूयूजर

"अगर यह एक त्रुटि है और ऐसा होता है, तो आप अपने कोड को डीबग कर सकते हैं" - उत्पादन में नहीं। मैं बहुत कुछ जानता हूँ कि जब मेरे पास सब कुछ नहीं है, तो मैं यह साबित करने की कोशिश करने के लिए क्या हुआ था परमात्मा की कोशिश करने की तुलना में एक लॉग है। उस सलाह (और उस कोड) के साथ, आप सभी वास्तव में जानते हैं कि 4 चीजों में से एक अशक्त थी, लेकिन कौन सी नहीं या क्यों।
वीएलए

1

आपके पास विधि लंबी है, लेकिन बहुत पठनीय है। अगर मैं आपके कोड आधार पर आने वाला एक नया डेवलपर था तो मैं देख सकता था कि आप काफी जल्दी क्या कर रहे थे। अधिकांश अन्य उत्तर (अपवाद को पकड़ने सहित) चीजों को अधिक पठनीय बनाने के लिए प्रतीत नहीं होते हैं और कुछ इसे मेरी राय में कम पठनीय बना रहे हैं।

यह देखते हुए कि संभवतः आपके पास उत्पन्न स्रोत पर नियंत्रण नहीं है और आपको लगता है कि वास्तव में यहाँ और कुछ गहरे नेस्टेड खेतों तक पहुँचने की आवश्यकता है, तो मैं एक विधि के साथ प्रत्येक गहरी नेस्टेड एक्सेस को लपेटने की सलाह दूंगा।

private int getFooBarBazInt() {
    if (wsObject.getFoo() == null) return -1;
    if (wsObject.getFoo().getBar() == null) return -1;
    if (wsObject.getFoo().getBar().getBaz() == null) return -1;
    return wsObject.getFoo().getBar().getBaz().getInt();
}

यदि आप खुद को इन विधियों का बहुत लेखन करते हुए पाते हैं या यदि आप इन सार्वजनिक स्थैतिक विधियों को बनाने के लिए खुद को लुभाते हैं तो मैं एक अलग ऑब्जेक्ट मॉडल बनाऊंगा, नेस्टेड कि आप कैसे चाहेंगे, केवल उन क्षेत्रों के बारे में जिनकी आप परवाह करते हैं, और वेब से परिवर्तित करें। आपके ऑब्जेक्ट मॉडल में सेवाएं ऑब्जेक्ट मॉडल।

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

उदाहरण के लिए:

public static class MyFoo {

    private int barBazInt;

    public MyFoo(Foo foo) {
        this.barBazInt = parseBarBazInt();
    }

    public int getBarBazInt() {
        return barBazInt;
    }

    private int parseFooBarBazInt(Foo foo) {
        if (foo() == null) return -1;
        if (foo().getBar() == null) return -1;
        if (foo().getBar().getBaz() == null) return -1;
        return foo().getBar().getBaz().getInt();
    }

}

1
return wsObject.getFooBarBazInt();

कानून के कानून लागू करने से,

class WsObject
{
    FooObject foo;
    ..
    Integer getFooBarBazInt()
    {
        if(foo != null) return foo.getBarBazInt();
        else return null;
    }
}

class FooObject
{
    BarObject bar;
    ..
    Integer getBarBazInt()
    {
        if(bar != null) return bar.getBazInt();
        else return null;
    }
}

class BarObject
{
    BazObject baz;
    ..
    Integer getBazInt()
    {
        if(baz != null) return baz.getInt();
        else return null;
    }
}

class BazObject
{
    Integer myInt;
    ..
    Integer getInt()
    {
        return myInt;
    }
}

0

वह उत्तर देना जो अन्य सभी से अलग लगता है।

मैं आपको एस NULLमें जांच करने की सलाह देता हूं if

कारण :

हमें अपने कार्यक्रम के दुर्घटनाग्रस्त होने का एक भी मौका नहीं छोड़ना चाहिए। NullPointer सिस्टम द्वारा उत्पन्न होता है। सिस्टम जनित अपवादों के व्यवहार की भविष्यवाणी नहीं की जा सकती है । आपको अपने प्रोग्राम को सिस्टम के हाथों में नहीं छोड़ना चाहिए जब आपके पास पहले से ही इसे अपने द्वारा संभालने का एक तरीका है। और एक्स्ट्रा सेफ्टी के लिए एक्सेप्शन हैंडलिंग मैकेनिज्म डाला। !!

शर्तों की जाँच के लिए अपना कोड पढ़ने के लिए इसे आसान बनाने के लिए:

if (wsObject.getFoo() == null || wsObject.getFoo().getBar() == null || wsObject.getFoo().getBar().getBaz() == null) 
   return -1;
else 
   return wsObject.getFoo().getBar().getBaz().getInt();

संपादित करें:

यहाँ आप इन मूल्यों को स्टोर करने के लिए की जरूरत है wsObject.getFoo(), wsObject.getFoo().getBar(), wsObject.getFoo().getBar().getBaz()कुछ चर में। मैं यह नहीं कर रहा हूं क्योंकि मुझे उस प्रकार के कार्यों का रिटर्न पता नहीं है।

कोई भी सुझाव प्रशंसनीय होगा..!!


क्या आपने getFoo पर विचार किया है () एक बहुत ही कालातीत ऑपरेशन? आपको चर में दिए गए मानों को संग्रहित करना चाहिए, हालाँकि यह स्मृति की बर्बादी है। आपका तरीका C प्रोग्रामिंग के लिए एकदम सही है।
xenteros

लेकिन कभी-कभी 1 मिलीसेकंड देर से होना बेहतर होता है, तो प्रोग्राम क्रैश हो रहा है @xenteros .. !!
जानकी गढ़िया

getFoo () दूसरे महाद्वीप पर स्थित सर्वर से मान प्राप्त कर सकता है। यह किसी भी समय हो सकता है: मिनट / घंटे ...
एक्सेंटरोस

wsObjectWebservice से लौटा मूल्य युक्त हो जाएगा .. !! सेवा को पहले से ही बुलाया wsObjectजाएगा और XMLएक वेबसर्वर प्रतिक्रिया के रूप में एक लंबा डेटा मिलेगा .. !! इसलिए दूसरे महाद्वीप पर स्थित सर्वर जैसा कुछ भी नहीं है क्योंकि getFoo()सिर्फ एक तत्व है जो एक गेटवे विधि है जो एक Webservice कॉल नहीं है .. !! @xenteros
जानकी

1
अच्छी तरह से पाने वालों के नामों से मुझे लगता है कि वे फू, बार और बाज वस्तुओं को लौटाएंगे: पी इसके अलावा अपने उत्तर के लिए उल्लिखित दोहरी सुरक्षा को हटाने पर विचार करें। मुझे नहीं लगता कि यह कोड के प्रदूषण को कोई वास्तविक मूल्य प्रदान करता है। स्थानीय स्थानीय चर और शून्य जाँच के साथ हमने कोड की शुद्धता सुनिश्चित करने के लिए पर्याप्त से अधिक किया है। यदि कोई अपवाद हो सकता है तो इसे एक माना जाना चाहिए।
मारियस के।

0

मैंने एक वर्ग लिखा है, Snagजो आपको वस्तुओं के पेड़ के माध्यम से नेविगेट करने के लिए एक मार्ग को परिभाषित करने देता है। यहाँ इसके उपयोग का एक उदाहरण है:

Snag<Car, String> ENGINE_NAME = Snag.createForAndReturn(Car.class, String.class).toGet("engine.name").andReturnNullIfMissing();

इसका मतलब यह है कि उदाहरण ENGINE_NAMEप्रभावी रूप Car?.getEngine()?.getName()से उस पर दिए गए उदाहरण पर कॉल करेगा , और nullयदि कोई संदर्भ वापस लौटा तो null:

final String name =  ENGINE_NAME.get(firstCar);

यह मावेन पर प्रकाशित नहीं हुआ है, लेकिन अगर किसी को यह उपयोगी लगता है तो यह यहाँ है (निश्चित रूप से वारंटी नहीं!)

यह थोड़ा बुनियादी है लेकिन यह काम करने के लिए लगता है। जाहिर है कि यह जावा और अन्य जेवीएम भाषाओं के अधिक हाल के संस्करणों के साथ अधिक अप्रचलित है जो सुरक्षित नेविगेशन का समर्थन करते हैं या Optional

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.