यह मेरे लिए एक सामान्य रूप से आम समस्या की तरह लगता है कि मध्यवर्ती डेवलपर्स के लिए जूनियर किसी बिंदु पर सामना करते हैं: वे या तो नहीं जानते हैं या उन अनुबंधों पर भरोसा नहीं करते हैं जो वे भाग ले रहे हैं और नल के लिए रक्षात्मक रूप से ओवरचेक करते हैं। इसके अतिरिक्त, जब अपना कोड लिखते हैं, तो वे कुछ इंगित करने के लिए लौटने वाले नल पर भरोसा करते हैं, इस प्रकार कॉल करने वाले को नल की जांच करने की आवश्यकता होती है।
इसे दूसरे तरीके से रखने के लिए, दो उदाहरण हैं जहाँ अशक्त जाँच सामने आती है:
जहां अनुबंध के संदर्भ में शून्य एक वैध प्रतिक्रिया है; तथा
जहां यह एक वैध प्रतिक्रिया नहीं है।
(२) आसान है। या तो assert
बयानों का उपयोग करें (दावे) या विफलता की अनुमति दें (उदाहरण के लिए, NullPointerException )। अभिक्रियाएँ एक अति-रेखांकित जावा सुविधा है जिसे 1.4 में जोड़ा गया था। वाक्य रचना है:
assert <condition>
या
assert <condition> : <object>
<condition>
एक बूलियन अभिव्यक्ति कहां है और <object>
एक ऐसी वस्तु है जिसके toString()
विधि का आउटपुट त्रुटि में शामिल किया जाएगा।
एक assert
बयान एक फेंकता है Error
( AssertionError
) अगर हालत सही नहीं है। डिफ़ॉल्ट रूप से, Java मुखरता को अनदेखा करता है। आप -ea
JVM के विकल्प को पास करके दावे को सक्षम कर सकते हैं । आप अलग-अलग कक्षाओं और पैकेजों के लिए मुखरता को सक्षम और अक्षम कर सकते हैं। इसका मतलब है कि आप विकास और परीक्षण के दौरान अभिकथन के साथ कोड को मान्य कर सकते हैं, और उन्हें उत्पादन वातावरण में अक्षम कर सकते हैं, हालांकि मेरे परीक्षण ने जोर देने से कोई प्रदर्शन प्रभाव नहीं दिखाया है।
इस मामले में मुखरता का उपयोग नहीं करना ठीक है क्योंकि कोड बस विफल हो जाएगा, जो कि यदि आप अभिकथन का उपयोग करते हैं तो क्या होगा। एकमात्र अंतर यह है कि जोर के साथ यह जल्द ही हो सकता है, अधिक सार्थक तरीके से और संभवतः अतिरिक्त जानकारी के साथ, जो आपको यह पता लगाने में मदद कर सकता है कि ऐसा क्यों हुआ यदि आप इसकी उम्मीद नहीं कर रहे थे।
(१) थोड़ा कठिन है। यदि आपके पास उस कोड पर कोई नियंत्रण नहीं है जिसे आप कॉल कर रहे हैं तो आप अटक गए हैं। यदि नल एक वैध प्रतिक्रिया है, तो आपको इसके लिए जांच करनी होगी।
यदि यह कोड है जिसे आप नियंत्रित करते हैं, हालांकि (और यह अक्सर मामला होता है), तो यह एक अलग कहानी है। प्रतिक्रिया के रूप में नल का उपयोग करने से बचें। उन तरीकों से, जो संग्रह लौटाते हैं, यह आसान है: खाली संग्रह (या सरणियाँ) के बजाय नल के बजाय हर समय बहुत अधिक।
गैर-संग्रह के साथ यह कठिन हो सकता है। इसे एक उदाहरण के रूप में देखें: यदि आपके पास ये इंटरफेस हैं:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
जहां पार्सर कच्चे उपयोगकर्ता इनपुट लेता है और कुछ करने के लिए पाता है, शायद अगर आप कुछ के लिए कमांड लाइन इंटरफ़ेस लागू कर रहे हैं। अब आप अनुबंध कर सकते हैं कि अगर कोई उचित कार्यवाही न हो तो यह शून्य हो जाता है। आप के बारे में बात कर रहे हैं कि अशक्त जाँच की ओर जाता है।
एक वैकल्पिक समाधान अशक्त कभी नहीं लौटना है और इसके बजाय अशक्त वस्तु पैटर्न का उपयोग करना है :
public class MyParser implements Parser {
private static Action DO_NOTHING = new Action() {
public void doSomething() { /* do nothing */ }
};
public Action findAction(String userInput) {
// ...
if ( /* we can't find any actions */ ) {
return DO_NOTHING;
}
}
}
की तुलना करें:
Parser parser = ParserFactory.getParser();
if (parser == null) {
// now what?
// this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
// do nothing
} else {
action.doSomething();
}
सेवा
ParserFactory.getParser().findAction(someInput).doSomething();
जो एक बेहतर डिजाइन है क्योंकि यह अधिक संक्षिप्त कोड की ओर जाता है।
उस ने कहा, शायद यह एक सार्थक त्रुटि संदेश के साथ अपवाद को फेंकने के लिए खोज () विधि के लिए पूरी तरह से उपयुक्त है - विशेष रूप से इस मामले में जहां आप उपयोगकर्ता इनपुट पर भरोसा कर रहे हैं। यह कोई स्पष्टीकरण के साथ एक सरल NullPointerException के साथ उड़ाने के लिए कॉलिंग विधि की तुलना में अपवाद को फेंकने के लिए खोज विधि के लिए बहुत बेहतर होगा।
try {
ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
userConsole.err(anfe.getMessage());
}
या यदि आपको लगता है कि ट्रूकॉलर / कैच मैकेनिज्म बहुत बदसूरत है, तो इसके बजाय डू नथिंग से आपकी डिफ़ॉल्ट कार्रवाई उपयोगकर्ता को प्रतिक्रिया प्रदान करनी चाहिए।
public Action findAction(final String userInput) {
/* Code to return requested Action if found */
return new Action() {
public void doSomething() {
userConsole.err("Action not found: " + userInput);
}
}
}