2009-11-08 15 views

उत्तर

127

निर्माण

try { ... } 
catch() { ... } /* You can even omit the() here */ 

try { ... } 
catch (Exception e) { ... } 

कि में समान हैं दोनों हर अपवाद try ब्लॉक के अंदर फेंक दिया पकड़ेगा (और, जब तक आप बस अपवाद लॉग इन करने के लिए इस का उपयोग कर रहे, से बचा जाना चाहिए)। अब इन पर नज़र डालें:

try { ... } 
catch() 
{ 
    /* ... */ 
    throw; 
} 

try { ... } 
catch (Exception e) 
{ 
    /* ... */ 
    throw; 
} 

try { ... } 
catch (Exception e) 
{ 
    /* ... */ 
    throw e; 
} 

पहली और दूसरी कोशिश पकड़ ब्लॉक बिल्कुल वही बात कर रहे हैं, वे केवल वर्तमान अपवाद rethrow, और कहा कि अपवाद अपने "स्रोत" और स्टैक ट्रेस रखेंगे।

तीसरा प्रयास-पकड़ ब्लॉक अलग है। जब यह अपवाद फेंकता है, तो यह स्रोत और स्टैक ट्रेस को बदल देगा, ताकि यह दिखाई दे सके कि इस विधि से अपवाद को फेंक दिया गया है, जिसमें उस रेखा से throw e उस विधि से प्रयास करें जिसमें ट्राइक-कैच ब्लॉक है।

आपको किस का उपयोग करना चाहिए? यह वास्तव में प्रत्येक मामले पर निर्भर करता है।

मान लें कि आपके पास Person कक्षा .Save() विधि है जो इसे डेटाबेस में रखेगी। मान लीजिए कि आपका एप्लिकेशन कहीं भी Person.Save() विधि निष्पादित करता है। यदि आपका डीबी व्यक्ति को बचाने से इंकार कर देता है, तो .Save() अपवाद फेंक देगा। क्या आपको इस मामले में throw या throw e का उपयोग करना चाहिए? अच्छा वह निर्भर करता है।

try { 
    /* ... */ 
    person.Save(); 
} 
catch(DBException e) { 
    throw new InvalidPersonException(
     "The person has an invalid state and could not be saved!", 
     e); 
} 

यह नए अपवाद फेंक होने के "इनर अपवाद" के रूप में DBException रखना चाहिए:

क्या मैं पसंद कर रही है

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

एक अंतिम टिप्पणी है, जब आप एक अपवाद की उम्मीद कर रहे हैं के रूप में, तुम सच में पकड़ने चाहिए कि एक विशिष्ट अपवाद है, और नहीं एक सामान्य Exception, यानी, अगर आप एक InvalidPersonException उम्मीद कर रहे हैं आप पसंद करते हैं चाहिए:

try { ... } 
catch (InvalidPersonException e) { ... } 

को
try { ... } 
catch (Exception e) { ... } 

गुड लक!

30

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

try 
{ 
    // do something 
} 
catch (Exception ex) 
{ 
    throw new Exception("Additional information...", ex); 
} 

एक ब्लॉग post मतभेद पर चर्चा नहीं है: जब आप स्टैक ट्रेस करने के लिए अतिरिक्त जानकारी जोड़ना चाहते हैं, लेकिन यह इस तरह प्रयोग किया जाता है

दूसरा दृष्टिकोण उपयोगी हो सकता है।

+0

खैर महान सामान पता करने के लिए है कि! – Myles

+0

तो फिर दूसरा क्यों उपयोग करें? क्या यह केवल पहले का उपयोग करना बेहतर है? – Karim

+1

दूसरा आसान काम करता है जब आपको विशिष्ट बहिष्कारों की जांच करने की आवश्यकता होती है - आउटऑफ्रेंज एक्सेप्शन दिमाग में आता है - या संदेश को लॉग इन करने की आवश्यकता होती है। पहला ऐसा लगता है कि वाइल्डकार्ड अपवाद हैंडलर {} पकड़ (...) { } सी ++ में। –

6

आप

try { } 
catch(Exception e) 
{ throw } 

उपयोग करें यदि आप (उदाहरण के लिए प्रवेश करने) इसे फिर से फेंकने से पहले अपवाद के साथ कुछ करना चाहता हूँ चाहिए। अकेला फेंक स्टैक ट्रेस को संरक्षित करता है।

+0

और यदि मैं "फेंक" के साथ "फेंक" को बदल देता हूं तो क्या होगा? – Karim

+3

जैसा कि डारिन ने बताया, "फेंकें" स्टैक ट्रेस को रीसेट करेगा। –

4

पैरामीटर रहित पकड़ और catch(Exception e) के बीच का अंतर यह है कि आपको अपवाद का संदर्भ मिलता है। फ्रेमवर्क संस्करण 2 से अप्रबंधित अपवाद एक प्रबंधित अपवाद में लपेटे गए हैं, इसलिए पैरामीटर रहित अपवाद अब किसी भी चीज़ के लिए उपयोगी नहीं है।

throw; और throw e; के बीच का अंतर यह है कि पहला व्यक्ति अपवादों को पुनर्स्थापित करने के लिए उपयोग किया जाता है और दूसरा उपयोग नव निर्मित अपवाद को फेंकने के लिए किया जाता है। यदि आप किसी अपवाद को पुनर्स्थापित करने के लिए दूसरे का उपयोग करते हैं, तो यह इसे एक नए अपवाद की तरह व्यवहार करेगा और सभी स्टैक जानकारी को उस स्थान से बदल देगा जहां से इसे मूल रूप से फेंक दिया गया था।

तो, आपने सवाल में विकल्पों में से किसी एक का उपयोग नहीं किया। आपको पैरामीटर रहित कैच का उपयोग नहीं करना चाहिए, और आपको अपवाद को पुनर्स्थापित करने के लिए throw; का उपयोग करना चाहिए।

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

try { 
    ... 
} catch (IOException e) { 
    ... 
    throw; 
} 

आप सभी जानकारी preservere के लिए किसी भी जानकारी जोड़ने के लिए जब अपवाद rethrowing, आप एक आंतरिक अपवाद के रूप में मूल अपवाद के साथ एक नया अपवाद बनाना चाहते हैं:

try { 
    ... 
} catch (IOException e) { 
    ... 
    throw new ApplicationException("Some informative error message", e); 
} 
संबंधित मुद्दे