2009-01-31 11 views
37

दिया गया: थ्रोबल अपवाद का सुपरक्लास है।नए अपवाद के बजाय थ्रोबल का उपयोग कब किया जाना चाहिए?

जब मैं अपने खुद के 'अपवाद' लिखने पर ग्रंथों को पढ़ने, मैं देख Throwable का उदाहरण catch ब्लॉक में इस्तेमाल किया जा रहा है और अन्य ग्रंथों new Exception() दिखाने catch ब्लॉक में इस्तेमाल किया जा रहा। मुझे अभी तक एक स्पष्टीकरण देखने को मिला है जब किसी को प्रत्येक का उपयोग करना चाहिए।

मेरा प्रश्न यह है कि, Throwable कब उपयोग किया जाना चाहिए और new Exception() कब उपयोग किया जाना चाहिए?

संपादित करें: का उपयोग कर catch या else ब्लॉक के अंदर या तो:

throw throwable; 

या

throw new Exception(); 
+1

आप 'नई' क्यों प्रयोग करते हैं? क्या आप पकड़ (थ्रोबल) बनाम पकड़ (अपवाद) की तुलना कर रहे हैं? –

+0

@ वुल्फमैन ड्रैगन: तो आप कैच ब्लॉक * अंदर * से थ्रोबल/अपवाद फेंक रहे हैं? क्या हम मानते हैं कि "फेंकने योग्य" उस ब्लॉक द्वारा पकड़ा गया एक मौजूदा थ्रोबल है? –

+0

@ ज़च स्क्रिप्वेना: नहीं, यह सामान्य सवाल था। मैंने सी ++ में अपवाद लिखे हैं लेकिन जावा में कभी नहीं, और मैं थोड़ा उलझन में हूं। यह मुद्दा जो इसे लाया गया है, यह है कि अगर संग्रह संग्रह नहीं होता है तो मुझे एक सहकर्मी का निर्माण करने वाले कोड के टुकड़े को 'अपवाद' पारित करने की आवश्यकता होती है। – WolfmanDragon

उत्तर

11

(टिप्पणियों से) मुद्दा यह है कि इस लाया कि मैं कोड एक सहकर्मी बनाने जा रहा है, तो एक संग्रह बना नहीं प्राप्त करता है की एक टुकड़ा करने के लिए एक 'अपवाद' उत्तीर्ण करने की आवश्यकता है।

उस मामले में, आप फेंकने के लिए एक अपवाद जाँच कर सकते हैं। आप Exception फेंक सकते हैं, इसके उपयुक्त मौजूदा उप-वर्ग (RuntimeException और इसके उप-वर्गों को छोड़कर अनचेक), या Exception (उदा। "CollectionBuildException") का एक कस्टम उप-वर्ग है। जावा अपवादों के साथ गति प्राप्त करने के लिए Java Tutorial on Exceptions देखें।

+0

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

+3

थ्रोबल अपवाद और त्रुटि का सुपरक्लास है। तीन वर्गों में से, मैं अपवाद को कार्य के लिए सबसे उपयुक्त मानने पर विचार करता हूं। अधिकांश लोग कोशिश-पकड़ ब्लॉक लिखते हैं जो केवल अपवाद और इसके उप-वर्गों के लिए दिखते हैं; वे एक नया थ्रोबल() को संभालने में सक्षम नहीं होंगे। –

+0

(cont'd) जब तक कि "कैच (थ्रोटेबल टी)" भी न हो। –

32

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

+6

अपवाद फेंक न दें, उपयुक्त अपवाद उप वर्ग या स्वयं को फेंक दें। उप-वर्ग वाले अपवाद का पूरा बिंदु यह है कि विभिन्न प्रकार की समस्याओं के अपने अपवाद हो सकते हैं। संदेश को शामिल करने और संभवतः कारण अपवाद को लपेटने के अलावा कोई अतिरिक्त "डेटा" जोड़ सकता है। –

+0

हाँ, यही मेरा मतलब था, अपवाद का एक उप-वर्ग फेंक दो। क्षमा करें काफी मुश्किल नहीं सोच रहा था। –

+1

यह सही उत्तर है। पूछने वाले ने एक दुर्भाग्यपूर्ण विकल्प बनाया है जिसके लिए एक सही चिह्नित करना है। इसके ऊपर एक अलग उत्तर पर सीएचओओ की टिप्पणी भी देखें जो इसे अच्छी तरह से पूरा करता है। – necromancer

1

थ्रोबल एक इंटरफ़ेस है, कक्षा नहीं। दो वर्ग थ्रोबल, अपवाद और त्रुटि का विस्तार करते हैं।

नियम यह है: अपवादों को पकड़ते समय आप जितना विशिष्ट हो सकते हैं - इसका मतलब है उदाहरण के लिए थ्रोबल के बजाय अपवाद को पकड़ना, और अपवाद के बजाय IOException।

त्रुटियों को न पकड़ें - त्रुटियां बग हैं। इसके बजाय कोड को ठीक करें।

यदि आपको बिल्कुल कुछ पकड़ना है, तो "पकड़ने योग्य" का उपयोग करें, लेकिन यह खराब रूप है।

+0

थ्रोबल एक ठोस वर्ग भी है। –

+0

अरे, असल में मैं इंप्रेशन के तहत था थ्रोबल एक इंटरफेस था जब तक मैंने देखा। निश्चित नहीं है कि यह क्यों है या यदि यह एक नई बात है। –

+0

यह इंगित करने के लिए धन्यवाद - मुझे लगता है कि मुझे पर्याप्त प्रत्यय द्वारा गुमराह किया गया था। –

7

आपको वास्तव में अपवाद नहीं लेना चाहिए और "नया अपवाद" के रूप में सामान्य रूप से एक नया फेंकना नहीं चाहिए।

try { 
    // Do some stuff here 
} 
catch (DivideByZeroException e) { 
    System.out.println("Can't divide by Zero!"); 
} 
catch (IndexOutOfRangeException e) { 
    // catch the exception 
    System.out.println("No matching element found."); 
} 
catch (Throwable e) { 
    throw e; // rethrow the exception/error that occurred 
} 

यह अच्छा अभ्यास, मैं विश्वास नहीं कर रहा है, एक अपवाद को पकड़ने और एक है कि था के बजाय कोई नया अपवाद फेंकने के लिए:

इसके बजाय, यदि आप बुलबुला अप करने के लिए अपवाद चाहते हैं तो बस निम्न कार्य करें जब तक आप एक उपयोगी कस्टम अपवाद नहीं उठाते हैं, तब तक आपके कोड ब्लॉक में उठाया जाता है जो मूल अपवाद के कारण के लिए पर्याप्त संदर्भ प्रदान करता है।

+0

आपका कोड जावा नहीं है। – starblue

+2

यह कोड DivideByZero और IndexOutOfRange अपवादों को त्याग देगा। फेंकने से पहले अपवाद को लॉग करना आम तौर पर एक बुरा विचार है। यदि कोई अपवाद लॉग ऑन है, तो आमतौर पर इसे स्टैक में स्तर पर करना सबसे अच्छा होता है जो वास्तव में त्रुटि को संभालने के लिए ज़िम्मेदार है, फिर से फेंकने के बिना। – erickson

+2

कोड प्रश्नकर्ता के प्रश्न को संबोधित करने के लिए है। सर्वोत्तम अभ्यास जो प्रश्नकर्ता के प्रश्न को प्रभावित नहीं करते हैं, वह इस उत्तर के दायरे से बाहर है। मैं सिर्फ यह दिखाना चाहता हूं कि आप अपवाद मामलों को संबोधित कर सकते हैं लेकिन फिर भी असाधारण अपवाद होने पर अपवाद को फिर से हटा दें। – MichaelD

0

जैसा कि मैंने जावा को पहली बार बाहर निकाला था, सिद्धांत यह था कि अपवादों के अलावा अन्य मामलों में नियंत्रण के हस्तांतरण के लिए थ्रोबल का उपयोग किया जा सकता है। मैंने इसे कभी भी इस तरह इस्तेमाल नहीं किया है (और शायद यह एक बहुत अच्छी चीज है)।

तो बस अपवाद (या बेहतर अभी तक, एक अधिक बढ़िया अपवाद) पकड़ लें।

0

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

+0

तो तर्कसंगत निर्णय लेने के लिए इसे मुख्य या सर्वलेट में पारित किया जाना चाहिए? नया अपवाद() अगर यह सिर्फ लॉग होना है? – WolfmanDragon

1

throw new Exception(); कुछ आप कभी नहीं कैच ब्लॉक में क्या करना चाहिए है, लेकिन आप के लिए है या क्रम में फेंक new SomeException(throwable); (पूर्ण स्टैक ट्रेस संरक्षण) के बजाय throw throwable; करने के लिए अपने विधि के एपीआई के अनुरूप कर सकते हैं, जैसे जब यह SomeException फेंकने की घोषणा करता है लेकिन आप कोड को कॉल कर रहे हैं जो IOException फेंक सकता है कि आप विधि throws खंड में जोड़ना नहीं चाहते हैं।

क्लॉज पूरी तरह से रोकने से बचने के लिए शायद सबसे आम मामला new RuntimeException(throwable); है। बहुत से लोग आपको बताएंगे कि यह एक भयानक दुर्व्यवहार है क्योंकि आपको चेक अपवादों का उपयोग करना चाहिए। आईएमओ वे गलत हैं और चेक अपवाद जावा भाषा डिज़ाइन में एक गलती है जो केवल बदसूरत, अनजान कोड में परिणाम देती है।

+1

अनचेक अपवाद "लीकी अबास्ट्रक्शन" का एक आम कारण है। http://www.joelonsoftware.com/articles/LeakyAbstractions.html वे एक-आकार-फिट-सभी त्रुटि रिपोर्टिंग के लिए ठीक हैं - कई मामलों में उपयोगी - लेकिन वे अमूर्तता के चेहरे में सही अपवाद हैंडलिंग का समर्थन नहीं कर सकते । – erickson

0

सभी अपवाद अंत में एक समस्या है ... यह भी कहते हैं कि त्रुटियां हैं बग का मतलब कुछ भी नहीं है।

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

0

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

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

इसमें नियमित त्रुटि स्थितियों ("नियमित" से मेरा मतलब है कि जेवीएम त्रुटियों के विपरीत) और उन स्थानों पर जहां आप नियंत्रण तंत्र के रूप में अपवाद का उपयोग कर रहे हैं।

0

आप एक "वापसी प्रकार" या तो ...

अगर हालत आप के लिए मना रहे हैं आम है, आप संसाधनों की एक बड़ी राशि खर्च कर रहे हैं कि हालत फोन करने के लिए वापस जाने के लिए के रूप में अपवाद उपयोग नहीं करना चाहिए दिनचर्या। अपवादों का निर्माण महंगा है।

मैंने उन मामलों को देखा है जहां तंग लूप ने अपवाद को "नकारात्मक" के रूप में फेंक दिया। आईडी आवंटन, इस दिनचर्या ने लगभग 99% CPU समय पर कब्जा कर लिया .. जब इसके बजाय एक दस्तावेज रिटर्न स्थिर में बदल दिया गया, तो यह 25% तक गिर गया।

5

केवल दो स्थानों पर आप कोड में शब्द Throwable देखना चाहिए:

public static void main(String args[]) 
{ 
    try 
    { 
     // Do some stuff 
    } 
    catch(Throwable t) 
    { 

    } 
} 

और

public class SomeServlet extends HttpServlet 
{ 
     public void doPost(HttpRequest request, HttpResponse response) 
     { 
     try 
     { 
      // Do some stuff 
     } 
     catch (Throwable t) 
     { 
       // Log 
     } 
     } 
} 
+5

यहां तक ​​कि इन दोनों में से कम से कम एक, आईएमओ होगा। 'थ्रोबल' (विशेष रूप से 'मुख्य' के बाहर) को पकड़ना आपदा के लिए एक नुस्खा है, क्योंकि आप बहुत व्यापक नेट कास्टिंग कर रहे हैं। केवल ऐप-स्तरीय अपवादों से अधिक थ्रोबल हैं। आम उदाहरण: ओओएम त्रुटियां। आप उन्हें लॉग इन करने जा रहे हैं, यदि लॉग के लेखन का बहुत ही कार्य किसी ऑब्जेक्ट को बनने का कारण बनता है (पढ़ें: आवंटित, बहुत ही प्रक्रिया से जो अभी विफल हुआ)? और जब वह * असफल हो जाता है, तो अब क्या? आपने उस जानकारी को खो दिया है जिसने मूल त्रुटि उत्पन्न की है, क्योंकि आपने एक नया कारण बनाया है जिसके बजाए प्रचार किया जाएगा। ऐसा लगता है कि ऐप सिर्फ मर नहीं जाता है। – cHao

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