2010-08-23 3 views
40

क्या जावा में अपवाद प्रसार पर कोई दिशानिर्देश हैं?अपवाद प्रसार (जावा में) पर दिशानिर्देश

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

क्या कोई अच्छी प्रथा है? कोई बुरा व्यवहार?

मुझे खेद है कि अगर मैं अस्पष्ट हूं, लेकिन मैं अपवादों से संबंधित प्रोग्रामिंग शैली पर कुछ (सामान्य) सलाह ढूंढ रहा हूं।

उत्तर

52

दिशानिर्देश है कि मुझे अतीत में मदद की है में शामिल हैं:

  • फेंक अपवाद विधि अपवाद नहीं संभाल कर सकते हैं, और अधिक महत्वपूर्ण बात, कॉल करने वाले को संभाला जाना चाहिए। इसका एक अच्छा उदाहरण Servlet API में मौजूद होता है - doGet() और doPost() कुछ परिस्थितियों में ServletException या IOException फेंक देता है जहां अनुरोध सही ढंग से नहीं पढ़ा जा सका। इन तरीकों में से कोई भी अपवाद को संभालने की स्थिति में नहीं है, लेकिन कंटेनर है (जिसके परिणामस्वरूप अधिकांश मामलों में 50x त्रुटि पृष्ठ होता है)।
  • अपवाद को बबल करें यदि विधि इसे संभाल नहीं सकती है। यह उपरोक्त का एक अनुशासनिक है, लेकिन अपवादों को पकड़ने के तरीकों पर लागू होता है। यदि पकड़े गए अपवाद को विधि द्वारा सही तरीके से संभाला नहीं जा सकता है, तो इसे बबल करना बेहतर होता है।
  • तुरंत अपवाद फेंक। यह अस्पष्ट लग सकता है, लेकिन यदि एक अपवाद परिदृश्य का सामना करना पड़ता है, तो अपवाद को फेंकने के लिए उचित समझा जाने वाला बिंदु तक त्रुटि कोड के माध्यम से विफलता को संभालने का प्रयास करने के बजाय असफलता के मूल बिंदु को इंगित करने वाला अपवाद फेंकना एक अच्छा अभ्यास है। । दूसरे शब्दों में, त्रुटि प्रबंधन के साथ मिश्रण अपवाद हैंडलिंग को कम करने का प्रयास करें।
  • या तो अपवाद लॉग करें या इसे बबल करें, लेकिन दोनों न करें। एक अपवाद लॉगिंग अक्सर इंगित करता है कि अपवाद स्टैक पूरी तरह से अवांछित रहा है, यह दर्शाता है कि अपवाद का कोई और बुलबुला नहीं हुआ है। इसलिए, एक ही समय में दोनों को करने की अनुशंसा नहीं की जाती है, क्योंकि यह अक्सर डिबगिंग में निराशाजनक अनुभव की ओर जाता है।
  • java.lang.Exception (चेक अपवाद) के उप-वर्गों का उपयोग करें, जब आप कॉलर को अपवाद को संभालने के लिए छोड़ दें। यदि कॉलर अपवाद को संभाल नहीं लेता है तो यह संकलक में त्रुटि संदेश फेंकने वाला होता है। हालांकि सावधान रहें, यह आम तौर पर कोड में अपवादों को "निगलने" के परिणामों में परिणाम देता है।
  • प्रोग्रामिंग त्रुटियों को सिग्नल करने के लिए java.lang.RuntimeException (अनचेक अपवाद) के उप-वर्गों का उपयोग करें। यहां अनुशंसित अपवाद वर्गों में IllegalStateException, IllegalArgumentException, UnsupportedOperationException इत्यादि शामिल हैं। फिर, किसी को अपवाद कक्षाओं जैसे नलपॉन्टरएक्सप्शन (लगभग हमेशा एक खराब प्रथा को फेंकने) के बारे में सावधान रहना चाहिए।
  • विभिन्न स्तरों में अपवादों के बारे में जानकारी संचारित करने के लिए अपवाद वर्ग पदानुक्रम का उपयोग करें। पदानुक्रम को लागू करके, आप कॉलर में अपवाद हैंडलिंग व्यवहार को सामान्यीकृत कर सकते हैं। उदाहरण के लिए, आप डोमेन अपवाद जैसे रूट अपवाद का उपयोग कर सकते हैं जिसमें कई उप-वर्ग हैं जैसे अमान्य कस्टमर एक्सेप्शन, अमान्य प्रॉडक्ट एक्सेप्शन इत्यादि। यहां चेतावनी यह है कि यदि आप अलग-अलग असाधारण परिदृश्य को अलग अपवाद के रूप में प्रस्तुत करते हैं तो आपका अपवाद पदानुक्रम बहुत तेज़ी से विस्फोट कर सकता है।
  • उन अपवादों को पकड़ने से बचें जिन्हें आप संभाल नहीं सकते हैं। बहुत स्पष्ट है, लेकिन बहुत से डेवलपर java.lang.Exception या java.lang को पकड़ने का प्रयास करते हैं। चूंकि सभी उप-वर्गीकृत अपवादों को पकड़ा जा सकता है, इसलिए "वैश्विक" अपवाद वर्ग पकड़े जाने पर एप्लिकेशन का रनटाइम व्यवहार अक्सर अस्पष्ट हो सकता है। आखिरकार, कोई आउटऑफमेरी एरर नहीं पकड़ना चाहता - किसी को इस तरह के अपवाद को कैसे संभालना चाहिए?
  • देखभाल के साथ अपवाद अपवाद। अपवाद को रेथ्रोइंग अपवाद स्टैक को रीसेट करता है। जब तक नई अपवाद वस्तु को मूल कारण प्रदान नहीं किया जाता है, यह हमेशा के लिए खो जाता है। अपवाद स्टैक को संरक्षित करने के लिए, किसी को नए अपवाद के कन्स्ट्रक्टर को मूल अपवाद ऑब्जेक्ट प्रदान करना होगा।
  • चेक किए गए अपवादों को अनचेक किए गए केवल तभी हटाएं जब आवश्यक हो। अपवाद को लपेटते समय, एक चेक अपवाद लपेटना और एक अनचेक फेंकना संभव है। यह कुछ मामलों में उपयोगी है, खासकर जब इरादा वर्तमान में निष्पादित थ्रेड को रद्द करना है। हालांकि, अन्य परिदृश्यों में यह थोड़ा दर्द पैदा कर सकता है, क्योंकि कंपाइलर चेक नहीं किए जाते हैं। इसलिए, एक अनचाहे के रूप में एक चेक अपवाद को अपनाने का मतलब अंधेरे से नहीं किया जाना है।
+4

मैं इस बात से सहमत नहीं हूं कि अपवाद को पुनर्स्थापित करते समय विवरण खो जाते हैं। –

+0

@Thorbjorn, आह हाँ। पर्याप्त कैफीन नहीं :-) मैंने वास्तविक इरादे को दर्शाने के लिए अंतिम खंड को दोहराया है। –

+0

@VineetReynolds "जब आप अपवाद को संभालने के लिए कॉलर को छोड़कर java.lang.Exception (चेक अपवाद) के उप-वर्गों का उपयोग करें" - क्या आपका मतलब "अपेक्षा" था? – gumkins

2

आपको जितनी जल्दी हो सके विधि को संभालना चाहिए, लेकिन इसे समझना चाहिए। यदि अपवाद को आपकी विधि से फेंकने का अर्थ नहीं है, लेकिन आप इसे संभाल नहीं सकते हैं, इसे किसी अन्य अपवाद में लपेटें और इस नए अपवाद को फेंक दें।

अपवाद के बारे में एक बुरा अभ्यास उन सभी को पकड़ना है (यह पॉकेटमैन नहीं है, यह जावा है!) तो catch(Exception e) या इससे भी बदतर catch(Throwable t) से बचें।

+0

"इसे किसी अन्य अपवाद में लपेटें" के साथ आपका क्या मतलब है? क्यों न केवल मूल अपवाद को फिर से फेंक दें? – wen

+0

@ डेनेटिक, जावा में आपको चेक अपवादों को पकड़ना होगा या उन्हें फेंकने की घोषणा करनी होगी। यह अनिवार्य रूप से लपेटने की ओर जाता है (या निगलने, जो एक बुरी चीज है)। अन्यथा आपकी फेंक सूची नियंत्रण से बाहर हो जाती है या आप एक इंटरफ़ेस में टक्कर डालते हैं जो आपको चेक अपवादों को फेंकने की अनुमति नहीं देता है। – Yishai

+2

क्योंकि कभी-कभी मूल अपवाद को पुनर्स्थापित करने से यह समझ में नहीं आता है, उदाहरण के लिए यदि आप किसी इकाई को प्राप्त करने के लिए डेटाबेस से कनेक्शन को संभालते हैं, और यह एक SQLException फेंकता है, तो आप वास्तव में एक SQLException को फिर से फेंकना नहीं चाहते हैं, बल्कि आपके अपने अपवाद में से एक, जो आपके कोड में समझ में आता है। –

संबंधित मुद्दे