2009-06-08 6 views
22
में NullPointerException परहेज

इस लाइन पर विचार करें:सुन्दरता जावा

if (object.getAttribute("someAttr").equals("true")) { // .... 

जाहिर है इस लाइन एक संभावित बग है, गुण null हो सकता है और हम एक NullPointerException मिल जाएगा।

पहले विकल्प:

if ("true".equals(object.getAttribute("someAttr"))) { // .... 

दूसरा विकल्प:

String attr = object.getAttribute("someAttr"); 
if (attr != null) { 
    if (attr.equals("true")) { // .... 

पहला विकल्प को पढ़ने के लिए अजीब लेकिन अधिक संक्षिप्त है तो हम दो विकल्पों में से एक करने के लिए इसे refactor करने के लिए की जरूरत है , जबकि दूसरा इरादा स्पष्ट है, लेकिन verbose।

पठनीयता के मामले में आप कौन सा विकल्प पसंद करते हैं?

उत्तर

27

मैं हमेशा

if ("true".equals(object.getAttribute("someAttr"))) { // .... 

का उपयोग किया है, क्योंकि हालांकि यह एक छोटे से अधिक यह बहुत कम वर्बोज़ है पढ़ने के लिए और मुझे लगता है कि यह काफी पठनीय है, तो आप इसे करने के लिए बहुत आसानी से

+3

मैं भी नहीं लगता है कि यह अधिक पढ़ने के लिए मुश्किल है की एक impl हो सकता है। –

1

मुझे पसंद आदत हो मुश्किल है विकल्प 1 और मैं तर्क दूंगा कि यह पर्याप्त पठनीय है।

विकल्प 3 बीटीडब्ल्यू एक getAttribute विधि पेश करना होगा जो पैरामीटर के रूप में डिफ़ॉल्ट मान लेता है।

+0

यह प्रश्न आपके विकल्प 3 के बारे में 'if' ब्लॉक के बारे में है: "आप हमेशा इस विधि पर भरोसा नहीं कर सकते हैं कि कभी भी शून्य मान –

+0

वापस नहीं आएगा, बेशक आप यह सुनिश्चित कर सकते हैं कि यह कभी भी डिफ़ॉल्ट मान के लिए शून्य नहीं लौटाता। – willcodejavaforfood

+0

विकल्प 3 DRY के अनुसार एक विधि में त्रुटि हैंडलिंग और शून्य जांच को स्थानांतरित करने के बारे में सब कुछ होगा। – willcodejavaforfood

0

Util.isEmpty(string) - रिटर्न string == null || string.trim().isEmpty() Util.notNull(string) रिटर्न "" यदि string == null, स्ट्रिंग अन्यथा। Util.isNotEmpty(string) रिटर्न! Util.isEmpty(string)

और हमारे पास एक सम्मेलन है कि तारों के लिए, Util.isEmpty(string) अर्थात् सत्य और Util.isNotEmpty(string) अर्थात् झूठा मतलब है।

17

दूसरा विकल्प में, आप शॉर्ट-सर्किट && का लाभ ले सकते:

String attr = object.getAttribute("someAttr"); 
if (attr != null && attr.equals("true")) { // .... 
+1

वास्तव में आप कर सकते हैं, लेकिन यह अनुकूलन के अनुकूल अनुकूलन है, हमेशा एक बुरा विचार। –

+6

हू, ऑप्टिमाइज़ेशन का समर्थन करता है? मुझे लगता है कि, यह विकल्प 1 से थोड़ा अधिक पठनीय है। – Jonik

+1

हां - शैली के मुद्दों में निश्चित उत्तर नहीं हैं। यही वह है जो आपने उपयोग किया है। व्यक्तिगत रूप से मैंने इस शैली का आदी हो क्योंकि यह भी बदतर है सी/सी ++ से वाक्यविन्यास प्राप्त करने वाली कई अन्य भाषाओं में केएस। और यदि आपके संगठन/प्रोजेक्ट में कोड सम्मेलन है, तो इसकी सिफारिशों का पालन करें। – laalto

1

हमेशा की तरह, कम कोड की आकांक्षा यह देखते हुए कि दोनों functionaly बराबर हैं। विशेष रूप से इस तरह के मामले में जहां पठनीयता का त्याग नहीं किया जाता है।

2

ऐसी कुछ स्थितियां हैं जहां संक्षिप्त दृष्टिकोण शुरू करने में गलत लगता है लेकिन प्रभावी ढंग से बेवकूफ बन जाता है। यह उनमें से एक है; दूसरा कुछ ऐसा है:

String line; 
while ((line = bufferedReader.readLine()) != null) { 
    // Use line 
} 

किसी स्थिति में साइड इफेक्ट्स? अकल्पनीय! जब आप विशेष पैटर्न को पहचानते हैं, तो यह विकल्प के मुकाबले मूल रूप से अच्छा है।

यह पैटर्न समान है - यह जावा में इतना आम है कि मैं किसी भी उचित अनुभवी डेवलपर को इसकी पहचान करने की अपेक्षा करता हूं। परिणाम सुखद संक्षेप में है। (असल में, मैं कभी-कभी सी # कोड देखता हूं जो एक ही मुहावरे का उपयोग करता है, अनावश्यक रूप से - समानता ऑपरेटर सी # में तारों के साथ ठीक काम करता है।)

नीचे पंक्ति: पहले संस्करण का उपयोग करें, और इससे परिचित हो जाएं।

0

यह एक बहुत अच्छा सवाल है। मैं आमतौर पर सुंदर नहीं का उपयोग करें:

if (object.getAttribute("someAttr") != null && object.getAttribute("someAttr").equals("true")) { // .... 

(और मैं इसे अब और का उपयोग नहीं होगा)

+4

अच्छा! क्या होगा getAttribute() वास्तव में साइड इफेक्ट्स हैं? कभी-कभी आप इसे एक बार चला रहे हैं, कभी-कभी आप इसे दो बार चला रहे हैं। –

+0

मैंने इसे "सामान्य प्रोग्रामिंग त्रुटियों" प्रश्न में लिखा है जो मैंने देखा है –

+0

टिप्पणियों के लिए धन्यवाद। पता था कि यह अच्छा नहीं था, मैं इस तरह की चीजों को सीखने के लिए यहां हूं। एक और सवाल: अगर इस एट्रिब्यूट() सिर्फ एक मानक गेटर विधि है - तो इस दृष्टिकोण के साथ समस्या क्या है - और इसका कोई साइड इफेक्ट नहीं है? – alexmeia

0

मैं एक जवाब है,

List<Map<String, Object>> group = jjDatabase.separateRow(db.Select("SELECT * FROM access_user_group WHERE user_id=1 ;")); 

वहाँ, मेरे डेटाबेस में 'access_user_group' कॉलम के रूप में "group_c80" नहीं है तो में प्राप्त (0) .Get ("group_c80") नल पॉइंटर एक्सेप्शन समझौते। लेकिन मैं इसे नीचे दिए गए कोड के माध्यम से नियंत्रित:

for (int j = 1; j < 100; j++) { 
        String rulId="0";//defult value,to privent null pointer exeption in group_c 
        try { 
         rulId = group.get(0).get("group_c" + j)).toString(); 
        } catch (Exception ex) { 
         ServerLog.Print("Handeled error in database for " + "group_c" + (j < 10 ? "0" + j : j) +"This error handeled and mot efect in program"); 
         rulId = "0"; 
        }} 
0

यहाँ मेरी दृष्टिकोण है, हालांकि एक PropertyUtil वर्ग की जरूरत है, लेकिन इसके लिए केवल एक बार लिखा:

/** 
* Generic method to encapsulate type casting and preventing nullPointers. 
* 
* @param <T>   The Type expected from the result value. 
* @param o   The object to cast. 
* @param typedDefault The default value, should be of Type T. 
* 
* @return Type casted o, of default. 
*/ 
public static <T> T getOrDefault (Object o, T typedDefault) { 
    if (null == o) { 
     return typedDefault; 
    } 
    return (T) o; 
} 

क्लाइंट कोड कर सकते हैं:

PropertyUtil.getOrDefault(obj.getAttribute("someAttr"), "").equals("true"); 

या, सूची के लिए:

PropertyUtil.getOrDefault(
    genericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST 
).contains(element); 
,210

या सूची की एक उपभोक्ता के लिए, कि अस्वीकार होगा वस्तु:

consumeOnlyList(
    PropertyUtil.getOrDefault(
     enericObjectMap.get(MY_LIST_KEY), Collections.EMPTY_LIST 
    ) 
) 

डिफ़ॉल्ट अशक्त वस्तु पैटर्न https://en.wikipedia.org/wiki/Null_Object_pattern