2013-10-03 13 views
23

यह मेरे लिए बहुत अजीब है। RuntimeExceptionException से विरासत, जो Throwable से विरासत में मिलता है।अपवाद कैच रनटाइम अपवाद क्यों नहीं पकड़ रहा है?

catch(Exception exc) { /* won't catch RuntimeException */ 

लेकिन

catch(Throwable exc) { /* will catch RuntimeException */ 

मैं जानता हूँ कि RuntimeException यह अनियंत्रित है कि में विशेष है। लेकिन मेरी समझ के लिए जो अपवादों को घोषित किया जाना है, यह लागू होता है कि वे पकड़े गए हैं या नहीं। और फिर भी, मुझे नहीं पता कि यह तर्क थ्रोबल को पकड़ने पर क्यों टूट जाएगा।

यह मेरे लिए बहुत प्रासंगिक है क्योंकि मेरे पास ऐसी स्थिति है जहां टर्मिनल ऑपरेशन में रनटाइम अपवादों को फेंक दिया जा सकता है। मुझे यकीन नहीं है कि इस पैटर्न के लिए नाम, लेकिन कुछ ऐसा है, मेरी कक्षा EmailRollerCallbacks की एक सरणी लेती है। कोड इस तरह दिखता है:

for(Callback cb : callbacks) { 
    try { 
     cb.call(item); 
    } 
    catch(Exception exc) { 
     logger.error("Error in callback: ", exc); 
    } 
} 

तो यह एक मामले में जहां एक OOME की तरह कुछ, के माध्यम से उड़ान भरने के लिए है क्योंकि अगर इन कॉलबैक में से एक सब मशीन स्मृति की खपत की जरूरत है, यह सुनिश्चित करने के रूप में बिल्ली के संचालन को प्रभावित करने जा रहा है अन्य लोग। लेकिन NullPointerException? या IndexOutOfBoundsException? वे कॉलबैक को प्रभावित करेंगे लेकिन दूसरों को दौड़ने से नहीं रोकेगा।

इसके अलावा, यह एक उद्यम डिजाइन का एक सा है। विभिन्न प्रोग्रामर या टीम आइटम को संसाधित करने के लिए कॉलबैक जोड़ सकते हैं, लेकिन उन्हें एक-दूसरे से अलग किया जाना चाहिए। इसका मतलब यह है कि प्रोग्रामर एक दूसरे से इन कॉलबैक को इन्सुलेट करने के लिए ज़िम्मेदार है, इसलिए मुझे यह सुनिश्चित करने के लिए उन पर भरोसा नहीं करना चाहिए कि त्रुटियां फिसलती नहीं हैं। Exception पकड़ना सही रेखा के बारे में होना चाहिए, लेकिन ऐसा इसलिए नहीं है क्योंकि RuntimeException के माध्यम से फिसल जाता है। तो मेरा सामान्य सवाल यह है कि यहां एक अच्छा पैटर्न क्या है? बस catch(Exception | RuntimeException exc), जो मुझे विश्वास है कि विरासत की वजह से एक वाक्यविन्यास त्रुटि है?

उत्तर

81

प्रश्न का आधार त्रुटिपूर्ण है, क्योंकि Exception पकड़ RuntimeException पकड़ता है। डेमो कोड:

public class Test { 
    public static void main(String[] args) { 
     try { 
      throw new RuntimeException("Bang"); 
     } catch (Exception e) { 
      System.out.println("I caught: " + e); 
     } 
    } 
} 

आउटपुट:

I caught: java.lang.RuntimeException: Bang 

आपका पाश समस्याओं होगा यदि:

  • callbacks बातिल
  • कुछ भी संशोधित करता callbacks जबकि पाश को क्रियान्वित किया जाता है (अगर यह थे एक सरणी के बजाय एक संग्रह)

शायद यही वह है जो आप देख रहे हैं?

+2

मेरा कोड दोबारा पढ़ें। यह सही है। मेरी इन्सुलेशन परत छोटी थी, क्योंकि रनटाइम अपवाद 'if (results.foo.bar()) से आया था {/ * कॉलबैक लागू करें * /}', जो एक एनपीई था। – djechlin

+6

@ डीजेक्लिन: आपकी पोस्ट * * * नहीं दिखाती है (if. ​​results.foo.bar()) - यह बहुत अस्पष्ट है कि आप वास्तव में इस बिंदु पर क्या पूछ रहे हैं ... –

18
catch (Exception ex) { ... } 

पकड़ RuntimeException होगा।

जो भी आप पकड़ ब्लॉक में डालते हैं उसके साथ-साथ इसके उप-वर्गों को भी पकड़ा जाएगा।

7

पकड़ने Exception एक RuntimeException

2

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

class A{//this class will never be initialized because class B won't intialize 
    static{ 
    try{ 
     classB.someStaticMethod(); 
    }catch(Exception e){ 
     sysout("This comment will never be printed"); 
    } 
} 
} 

class B{//this class will never be initialized 
static{ 
    int i = 1/0;//throw run time exception 
} 

public static void someStaticMethod(){} 
} 

और हाँ ... Exception को पकड़ने से रन टाइम अपवाद भी मिलेंगे।

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