कोशिश / पकड़ / फेंक और कोशिश / पकड़ (ई) / फेंक ई के बीच का अंतर


103

दोनों के बीच क्या अंतर है

try { }
catch
{ throw; }

तथा

try { }
catch(Exception e)
{ throw e;}

?

और मुझे एक या दूसरे का उपयोग कब करना चाहिए?

जवाबों:


151

निर्माण

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;
}

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

तीसरा ट्राइ-कैच ब्लॉक अलग है। जब यह अपवाद फेंकता है, तो यह स्रोत और स्टैक ट्रेस को बदल देगा, ताकि यह दिखाई दे कि इस विधि से अपवाद को फेंक दिया गया है, उस 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 को नए अपवाद के "इनर एक्सेप्शन" के रूप में डाला जाना चाहिए। इसलिए जब आप इस InvalidPersonException का निरीक्षण करते हैं, तो स्टैक ट्रेस में जानकारी सहेजने की विधि (जो आपके लिए समस्या को हल करने के लिए पर्याप्त हो सकती है) शामिल होगी, लेकिन यदि आवश्यक हो, तो भी आपके पास मूल अपवाद तक पहुंच है।

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

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

सेवा

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

सौभाग्य!


34

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

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

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

मतभेदों पर चर्चा करते हुए एक ब्लॉग पोस्ट है


खैर यह जानने के लिए बहुत अच्छी बात है!
माइल्स

तो दूसरे का उपयोग क्यों करें? क्या केवल पहले एक का उपयोग करना बेहतर है?
करीम

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

1
डेविड, जो केवल कैच (अपवाद ई) भाग पर लागू होता है । और यह throwबनाम से अलग है throw e
हेनक होल्टरमैन

6

आपको उपयोग करना चाहिए

try { }
catch(Exception e)
{ throw }

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


और क्या होगा अगर मैं "फेंक" को "फेंक ई" के साथ बदल दूं?
करीम

5

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

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

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

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

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

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

try {
   ...
} catch (IOException e) {
   ...
   throw new ApplicationException("Some informative error message", e);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.