स्टैक ट्रेस खोए बिना जावा में पुनर्विचार अपवाद


417

C # में, मैं throw;स्टैक ट्रेस को संरक्षित करते हुए एक अपवाद को पुनर्व्यवस्थित करने के लिए कथन का उपयोग कर सकता हूं :

try
{
   ...
}
catch (Exception e)
{
   if (e is FooException)
     throw;
}

क्या जावा में ऐसा कुछ है ( जो मूल स्टैक ट्रेस नहीं खोता है )?


4
आपको क्यों लगता है कि यह मूल स्टैकट्रेस खो देता है? जब आप नई SomeOtherException को फेंकते हैं, तो इसे ढीला करने का एकमात्र तरीका है और निर्माता या initCause () में मूल कारण निर्दिष्ट करना भूल जाते हैं।
एकरनोकड '

4
मेरा मानना ​​है कि यह कैसे कोड .Net में व्यवहार करता है, लेकिन मैं अब सकारात्मक नहीं हूं। यह सार्थक हो सकता है कि या तो इसे कहीं और देखें या एक छोटा परीक्षण चलाएं।
ripper234

11
Throwableउन्हें फेंकने से संशोधित नहीं होता है। स्टैक ट्रेस को अपडेट करने के लिए आपको कॉल करना होगा fillInStackTrace()। आसानी से इस विधि को एक के निर्माता में कहा जाता है Throwable
रॉबर्ट

50
सी # में, हाँ, throw e;स्टैकट्रेस खो देगा। लेकिन जावा में नहीं।
टिम गुडमैन

जवाबों:


560
catch (WhateverException e) {
    throw e;
}

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


4
नमस्ते, InterruptedException e एक फेंकने वाला अपवाद संदेश देता है जब मैं फेंक ई लाइन जोड़ता हूं। ऐसा नहीं है अगर मैं इसे व्यापक अपवाद ई के साथ बदल दूं। यह कैसे ठीक से किया जाना चाहिए?
जेम्स पी।

1
@ जेम्स, मैंने अभी देखा कि यदि फ़ंक्शन घोषणा में "थ्रोन्स XxxException" को जोड़कर संदेश चला जाता है।
10

2
जावा में इस तरह के पुनर्वसन के लिए संकलक अधिक बौद्धिक है। अब यह विधि युक्त विशिष्ट "थ्रो" अपवादों के साथ ठीक काम करता है।
वाल्डेमर वोसिस्की

193
@James यदि आप अनहेल्दी catch(Exception e) { throw e; }होंगे। यदि आप catch(InterruptedException ie) { throw ie; }इसे संभाला जाएगा। अंगूठे के एक नियम के रूप में, नहीं catch(Exception e)- यह पॉकेमॉन नहीं है, और हम उन्हें नहीं पकड़ना चाहते हैं!
corsiKa

3
@corsiKa यह जरूरी नहीं है कि आप उन्हें "कैच ऑल" करना नहीं चाहते हैं, यह सिर्फ एक अलग उपयोग का मामला है। यदि आपके पास एक शीर्ष-स्तरीय लूप या ईवेंट हैंडलर है (उदाहरण के लिए, थ्रेड के रन के अंदर) यदि आप कम से कम RuntimeException को नहीं पकड़ते हैं और इसे लॉग करते हैं, तो आप अक्सर अपवाद को पूरी तरह से याद करेंगे और चुपचाप एक महत्वपूर्ण लूप के बाहर तोड़ देंगे। अक्सर एक बार की विफलता है। यह प्लगइन कार्यक्षमता के लिए भी वास्तव में अच्छा है, जहां आप नहीं जानते कि अतिरिक्त कोड क्या कर सकता है या फेंक सकता है ... इन कैचिंग अपवाद जैसे टॉप-डाउन उपयोगों के लिए अक्सर न केवल एक अच्छा विचार है, बल्कि एक सर्वोत्तम अभ्यास भी है।
बिल के

82

मैं चाहूंगा की:

try
{
    ...
}
catch (FooException fe){
   throw fe;
}
catch (Exception e)
{
    // Note: don't catch all exceptions like this unless you know what you
    // are doing.
    ...
}

6
निश्चित रूप से जावा में सामान्य अपवादों की तुलना में विशिष्ट अपवादों को पकड़ना और उदाहरण के लिए जाँच करना उचित है। +1
amischiefr

8
-1 क्योंकि आपको कभी भी सादे "अपवाद" को नहीं पकड़ना चाहिए जब तक कि आपको पता न हो कि आप क्या कर रहे हैं।
स्ट्रोबोस्कोप

19
@Stroboskop: सच है, लेकिन इसका जवाब देना सबसे अच्छा है (समान) कोड का उपयोग करें जैसा कि प्रश्न में है!
user85421

14
कभी-कभी सभी अपवादों को पकड़ना ठीक है। जैसे कि जब आप टेस्ट केस लिख रहे हों। या लॉगिंग उद्देश्यों के लिए। या मुख्य में जहां पकड़ने का मतलब दुर्घटनाग्रस्त नहीं है।
जॉन हेनकेल

1
@ जॉनहेनकेल और अन्य: मान्य अंक प्रेरित। मैंने यह स्पष्ट करने के लिए प्रश्न को अपडेट किया कि पकड़ना Exceptionआमतौर पर ज्यादातर (लेकिन सभी नहीं) मामलों में, सही काम नहीं है।
प्रति लुंडबर्ग

74

आप अपवाद को दूसरे में भी लपेट सकते हैं और मूल स्टैक ट्रेस को अपवाद पैरामीटर के रूप में एक्सेप्शन में पास करके रख सकते हैं:

try
{
   ...
}
catch (Exception e)
{
     throw new YourOwnException(e);
}

8
मैं एक संदेश के साथ जोड़ने की सलाह भी throw new YourOwnException("Error while trying to ....", e);
जुलिएन

यह वही है जो मैं देख रहा था, विशेष रूप से पहली टिप्पणी से संस्करण जहां आप अपना संदेश पास कर सकते हैं
Csaba

यह त्रुटि संदेश को सही ढंग से दिखाता है लेकिन स्टैक ट्रेस त्रुटि रेखा को 'थ्रो न्यू ....... (ई)' के रूप में दिखाता है जो मूल रेखा नहीं है क्योंकि यह अपवाद है।
ऐशबर्न आरके

22

जावा में लगभग समान है:

try
{
   ...
}
catch (Exception e)
{
   if (e instanceof FooException)
     throw e;
}

5
नहीं, जब तक आप एक नई अपवाद-वस्तु को तुरंत नहीं करते हैं तब तक स्टैकट्रेस समान रहता है।
ममेन्थ

28
मैं FooException
dfa

3
इस विशिष्ट मामले में मैं सहमत हूं, लेकिन एक विशिष्ट पकड़ जोड़ना सही विकल्प नहीं हो सकता है - कल्पना करें कि आपके पास सभी अपवादों के लिए कुछ सामान्य कोड हैं और किसी विशेष अपवाद के बाद, इसे पुन: फेंक दें।
एल्विस

1
@MarkusLausberg लेकिन अंत में अपवादों को नहीं पकड़ता है।
रॉबर्ट

हां, लेकिन यह सवाल नहीं था।
मार्कस लोसबर्ग

14

जावा में, आप केवल आपके द्वारा पकड़े गए अपवाद को फेंक देते हैं, इसलिए throw eसिर्फ इसके बजाय throw। जावा स्टैक ट्रेस बनाए रखता है।


6

कुछ इस तरह

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

5
public int read(byte[] a) throws IOException {
    try {
        return in.read(a);
    } catch (final Throwable t) {
        /* can do something here, like  in=null;  */
        throw t;
    }
}

यह एक ठोस उदाहरण है जहां विधि एक फेंकता है IOExceptionfinalसाधन tकेवल एक अपवाद कोशिश ब्लॉक से फेंका पकड़ कर सकते हैं। अतिरिक्त पठन सामग्री यहाँ और यहाँ मिल सकती है


1
यह अंतिम होना जरूरी नहीं है। देखें docs.oracle.com/javase/7/docs/technotes/guides/language/… और stackoverflow.com/a/6889301/131160
jcsahnwaldt का कहना है कि GoFundMonit

3

यदि आप एक अन्य अपवाद (अधिक जानकारी प्रदान करने के लिए) में कैच किए गए एक्सट्रैक्शन को लपेटते हैं या यदि आप कैच किए गए एक्सट्रिशन को रीहैरो करते हैं, तो स्टैक ट्रेस prserved है।

try{ ... }catch (FooException e){ throw new BarException("Some usefull info", e); }


2

मैं बस एक ऐसी ही स्थिति बना रहा था जिसमें मेरा कोड संभावित रूप से कई अलग-अलग अपवादों को फेंकता है जिन्हें मैं सिर्फ पुनर्विचार करना चाहता था। ऊपर वर्णित समाधान मेरे लिए काम नहीं कर रहा था, क्योंकि एक्लिप्स ने मुझे बताया कि throw e;एक अखंड अपवाद की ओर जाता है, इसलिए मैंने अभी किया:

try
{
...
} catch (NoSuchMethodException | SecurityException | IllegalAccessException e) {                    
    throw new RuntimeException(e.getClass().getName() + ": " + e.getMessage() + "\n" + e.getStackTrace().toString());
}

मेरे लिए काम किया .... :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.