जवाबों:
निर्माण
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) { ... }
सौभाग्य!
पहला स्टैक ट्रेस को संरक्षित करता है जबकि दूसरा इसे रीसेट करता है। इसका अर्थ है कि यदि आप दूसरे दृष्टिकोण का उपयोग करते हैं तो अपवाद का स्टैक ट्रेस हमेशा इस विधि से शुरू होगा और आप मूल अपवाद ट्रेस खो देंगे जो अपवाद लॉग पढ़ने वाले किसी व्यक्ति के लिए विनाशकारी हो सकता है क्योंकि वह अपवाद के मूल कारण का कभी पता नहीं लगाएगा। ।
जब आप स्टैक ट्रेस में अतिरिक्त जानकारी जोड़ना चाहते हैं, तो दूसरा तरीका उपयोगी हो सकता है, लेकिन इसका उपयोग इस तरह किया जाता है:
try
{
// do something
}
catch (Exception ex)
{
throw new Exception("Additional information...", ex);
}
मतभेदों पर चर्चा करते हुए एक ब्लॉग पोस्ट है ।
throw
बनाम से अलग है throw e
।
आपको उपयोग करना चाहिए
try { }
catch(Exception e)
{ throw }
यदि आप इसे फिर से फेंकने से पहले अपवाद के साथ कुछ करना चाहते हैं (उदाहरण के लिए लॉगिंग)। अकेला फेंक स्टैक ट्रेस को संरक्षित करता है।
एक पैरामीटर रहित कैच और एक अंतर यह 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);
}