2011-10-31 22 views
12

एक जेनेरिक (java.lang.Exception) अपवाद फेंकने के लिए क्यों निराश किया जाता है, जब यह आमतौर पर किसी विधि के भीतर सबसे सशर्त विफलताओं को संभालने के लिए पर्याप्त होता है? मैं समझता हूं कि यदि कोई विधि कई प्रकार के अपवादों को फेंक सकती है तो अपवाद के विशिष्ट उप-वर्गों को फेंकने से थोड़ा सा प्रबंधन स्पष्ट हो सकता है, लेकिन सामान्य विफल/सफल मामले में मुझे लगता है कि अपवाद पर्याप्त से अधिक कार्य करता है।जेनेरिक अपवाद फेंकने से हतोत्साहित?

+0

[जावा या सी # में अपवाद प्रबंधन के लिए सर्वोत्तम प्रथाओं] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c-sharp) –

उत्तर

20

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

+1

यह एक और महत्वपूर्ण समस्या है, +1। –

+0

@MarkPeters हालांकि मैं शायद ही कभी "कभी नहीं" कहता हूं, क्योंकि मुझे लगता है कि सबसे खराब एंटी-पैटर्न भी विपरीत परिस्थितियों में सही जवाब हो सकता है, अपवादों से सावधान रहना सबसे अच्छा है। कभी-कभी उन्हें कोड द्वारा संभाला जाना होगा जिसे आपने नहीं लिखा था और आप पूरी दुकान में अनावश्यकता को खत्म कर देंगे। फिर, ज़ाहिर है, ऐसे लोग हैं जो 'थ्रोबल' पकड़ते हैं जैसे कि यह कोई बड़ा सौदा नहीं है: डी –

+0

+1 - वास्तव में बहुत अच्छा बिंदु। – DerMike

5

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

साथ ही, फेंक "अपवाद" ही आप मूल रूप से अपने कोड की कॉल है कि वे अपवाद के किसी भी वर्ग से इनकार नहीं कर सकते हैं कह रहे हैं से। एक IOException एक NumberFormatException कर सकते हैं, हो सकता है, आदि

1

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

3

हमेशा की तरह: यह निर्भर करता है।

मुझे लगता है कि एपीआई के बीच एक अंतर है जिसे आप दूसरों के सामने प्रकट करते हैं। यह कुछ समय के लिए जी सकता है। उस स्थिति में आप नहीं जानते कि कॉलर अपने मामले के लिए सबसे अच्छा क्या मानता है।

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

0

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

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

प्रोग्रामिंग में बहुत सी बातें की तरह, यह कितनी दूर तुम जाओ का एक सवाल है। मैं आमतौर पर लगभग हर प्रोजेक्ट में एक सामान्य "BadInputException" बनाता हूं, जिस पर मैं काम करता हूं, और इसे किसी भी समय उपयोगकर्ता इनपुट मान्यता मानदंडों में विफलता देता हूं। फिर मैं BadInputException को पकड़ सकता हूं और स्क्रीन पर संदेश फेंक सकता हूं। अगर मैं एक जटिल वर्ग बनाता हूं जो असंगत डेटा और उस तरह की चीज के लिए अपवाद फेंकता है, तो मैं आमतौर पर इसके लिए एक अपवाद वर्ग बना देता हूं। जैसे कि मैं "TalkToDatabase" कक्षा बनाता हूं, मैं एक "TalkToDatabaseException" बनाउंगा। (शायद उससे अधिक अगर कई प्रकार के अपवाद हैं तो मुझे पता है कि मैं पकड़ना चाहता हूं, लेकिन कम से कम एक।)

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

// Very bad idea! Don't do this! 
catch (Exception ex) 
{ 
    if (ex.getMessage().equals("Invalid foo")) 
    ... handle bad foo ... 
    else if (ex.getMessage().equals("Plugh is over maximum")) 
    ... handle bad plugh ... 
    ... etc ... 
} 

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

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