आइए उस स्थिति पर विचार करें जहां आपके पास प्रदान किया गया कोड है:
public void delete() throws IOException, SQLException { // Non-Compliant
/* ... */
}
यहां खतरा यह है कि कोड जिसे आप कॉल करने के लिए लिखते हैं, delete()
वह दिखेगा:
try {
foo.delete()
} catch (Exception e) {
/* ... */
}
यह भी बुरा है। और यह एक अन्य नियम के साथ पकड़ा जाएगा जो बेस एक्सेप्शन क्लास को झंडे को पकड़ता है।
कुंजी कोड लिखना नहीं है जो आपको बुरा कोड कहीं और लिखना चाहता है।
नियम जो आप सामना कर रहे हैं, बल्कि एक आम है। चेकस्टाइल में इसके डिजाइन नियम हैं:
ThrowsCount
प्रतिबंधित एक निर्दिष्ट गिनती (डिफ़ॉल्ट रूप से 1) के लिए कथन फेंकता है।
Rationale: अपवाद एक विधि के इंटरफेस का हिस्सा हैं। कई अलग-अलग निहित अपवादों को फेंकने के लिए एक विधि की घोषणा करना अपवाद को संभालता है और खराब प्रोग्रामिंग प्रथाओं को पकड़ता है जैसे कैच (अपवाद पूर्व) लिखना। यह चेक डेवलपर्स को एक पदानुक्रम में अपवाद डालने के लिए मजबूर करता है जैसे कि सबसे सरल मामले में, केवल एक प्रकार के अपवाद की आवश्यकता होती है एक कॉलर द्वारा जाँच की जाती है लेकिन किसी भी उपवर्ग को विशेष रूप से आवश्यक होने पर पकड़ा जा सकता है।
यह समस्या का सटीक वर्णन करता है और समस्या क्या है और आपको ऐसा क्यों नहीं करना चाहिए। यह एक अच्छी तरह से स्वीकार किया गया मानक है कि कई स्थैतिक विश्लेषण उपकरण पहचान और ध्वज लगाएंगे।
और जब आप इसे भाषा डिजाइन के अनुसार कर सकते हैं, और कई बार ऐसा हो सकता है जब यह करना सही है, तो यह कुछ ऐसा है जिसे आपको देखना चाहिए और तुरंत "उम, मैं ऐसा क्यों कर रहा हूं?" यह आंतरिक कोड के लिए स्वीकार्य हो सकता है जहां सभी को कभी भी अनुशासित नहीं किया जाता है catch (Exception e) {}
, लेकिन अधिक बार मैंने नहीं देखा है कि लोगों ने विशेष रूप से आंतरिक स्थितियों में कोनों को काट दिया है।
अपने वर्ग का उपयोग करने वाले लोगों को बुरा कोड लिखना न दें।
मुझे यह बताना चाहिए कि जावा एसई 7 के साथ इसका महत्व कम हो जाता है और बाद में क्योंकि एक एकल कैच स्टेटमेंट कई अपवादों को पकड़ सकता है ( ओरेकल से बेहतर टाइप चेकिंग के साथ कई एक्सेप्शन टाइप और रीथ्रोइंग एक्सेप्शन को पकड़ना )।
जावा 6 और इससे पहले, आपके पास ऐसा कोड होगा जो दिखता था:
public void delete() throws IOException, SQLException {
/* ... */
}
तथा
try {
foo.delete()
} catch (IOException ex) {
logger.log(ex);
throw ex;
} catch (SQLException ex) {
logger.log(ex);
throw ex;
}
या
try {
foo.delete()
} catch (Exception ex) {
logger.log(ex);
throw ex;
}
जावा 6 के साथ इनमें से कोई भी विकल्प आदर्श नहीं हैं। पहला दृष्टिकोण DRY का उल्लंघन करता है । एक ही काम कर रहे कई ब्लॉक, बार-बार - प्रत्येक अपवाद के लिए एक बार। आप अपवाद को लॉग इन करना चाहते हैं और इसे रीथ्रो करना चाहते हैं? ठीक। प्रत्येक अपवाद के लिए कोड की समान पंक्तियाँ।
दूसरा विकल्प कई कारणों से खराब है। सबसे पहले, इसका मतलब है कि आप सभी अपवादों को पकड़ रहे हैं। नल पॉइंटर वहां पकड़ा जाता है (और ऐसा नहीं होना चाहिए)। इसके अलावा, आप एक Exception
जिसका अर्थ यह है कि विधि हस्ताक्षर हो जाएगा deleteSomething() throws Exception
जो बस एक गड़बड़ आगे ढेर हो जाता है, क्योंकि आपके कोड का उपयोग करने वाले लोग अब मजबूर हो रहे हैं catch(Exception e)
।
जावा 7 के साथ, यह उतना महत्वपूर्ण नहीं है क्योंकि आप इसके बजाय कर सकते हैं:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
इसके अलावा, यदि जाँच की जा रही है कि कोई अपवाद के प्रकार को नहीं पकड़ता है:
public void rethrowException(String exceptionName)
throws IOException, SQLException {
try {
foo.delete();
} catch (Exception e) {
throw e;
}
}
प्रकार चेकर पहचान जाएगा कि केवल प्रकार के या e
हो सकता है । मैं अभी भी इस शैली के उपयोग के बारे में अधिक उत्साही नहीं हूं, लेकिन यह जावा 6 के तहत खराब कोड के रूप में पैदा नहीं कर रहा है (जहां यह आपको मजबूर कर देगा कि विधि हस्ताक्षर सुपरक्लास हो जो अपवादों का विस्तार करते हैं)।IOException
SQLException
इन सभी परिवर्तनों के बावजूद, कई स्थिर विश्लेषण उपकरण (सोनार, पीएमडी, चेकस्टाइल) अभी भी जावा 6 शैली गाइडों को लागू कर रहे हैं। यह कोई बुरी बात नहीं है। मैं इन्हें अभी भी लागू किए जाने की चेतावनी से सहमत हूं , लेकिन आप अपनी टीम की प्राथमिकता के अनुसार इन्हें प्रमुख या मामूली में बदल सकते हैं।
अपवाद जाँच की जानी चाहिए, तो या अनियंत्रित ... कि की बात है जी आर ई एक टी बहस है कि एक आसानी से तर्क के प्रत्येक पक्ष लेने के अनगिनत ब्लॉग पोस्ट पा सकते हैं। हालाँकि, यदि आप जाँच किए गए अपवादों के साथ काम कर रहे हैं, तो आपको संभवतः कई प्रकार के फेंकने से बचना चाहिए, कम से कम जावा 6 के तहत।