2010-08-16 13 views
516

जावा में, मैं ऐसा कुछ करना चाहता हूं:क्या मैं एक ही पकड़ खंड में एकाधिक जावा अपवादों को पकड़ सकता हूं?

try { 
    ...  
} catch (IllegalArgumentException, SecurityException, 
     IllegalAccessException, NoSuchFieldException e) { 
    someCode(); 
} 

... इसके बजाय:

try { 
    ...  
} catch (IllegalArgumentException e) { 
    someCode(); 
} catch (SecurityException e) { 
    someCode(); 
} catch (IllegalAccessException e) { 
    someCode(); 
} catch (NoSuchFieldException e) { 
    someCode(); 
} 

क्या ऐसा करने का कोई तरीका है?

उत्तर

849

यह संभव है since Java 7। ट्राई-कैच ब्लॉक के लिए सिंटैक्स है:

try { 
    ... 
} catch (IOException | SQLException ex) { 
    ... 
} 

जावा 7 से पहले यह संभव नहीं था। याद रखें, अगर सभी अपवाद समान श्रेणी पदानुक्रम से संबंधित हैं, तो आप बस उस बेस अपवाद प्रकार को पकड़ सकते हैं। एकमात्र अन्य तरीका अपने अपवाद ब्लॉक में प्रत्येक अपवाद को पकड़ना है।

संपादित करें: ध्यान दें कि जावा 7 में, आप एक्सेप्शन ए और अपवाद बी दोनों को उसी ब्लॉक में नहीं पकड़ सकते हैं यदि अपवाद बी विरासत में प्राप्त होता है, या तो सीधे या परोक्ष रूप से, अपवाद से। संकलक शिकायत करेगा: The exception ExceptionB is already caught by the alternative ExceptionA

+67

टीटी - 'bitwise या' (' | ') ऑपरेटर को फिर से परिभाषित क्यों करें? एक अल्पविराम, या ऑपरेटर का उपयोग क्यों न करें जिसका अर्थ समान है, 'तार्किक या' ('||')? – ArtOfWarfare

+8

@ArtOfWarfare शायद उन्होंने सोचा था कि वे [एकाधिक सीमाओं] (http://docs.oracle.com/javase/tutorial/java/generics/bounded.html) के लिए वाक्यविन्यास के साथ पहले ही आ चुके हैं, इससे कोई फर्क नहीं पड़ता जेनरिक। – JimmyB

+0

@JimmyB क्या आप जेनेरिक के लिए कई सीमाओं के बारे में अधिक समझा सकते हैं? धन्यवाद। – ZhaoGang

15

नहीं, प्रति ग्राहक एक।

आप java.lang.Exception की तरह एक सुपरक्लास पकड़ सकते हैं, जब तक आप सभी मामलों में एक ही कार्रवाई करते हैं।

try { 
    // some code 
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception 
    e.printStackTrace(); 
} 

लेकिन यह सबसे अच्छा अभ्यास नहीं हो सकता है। आपको केवल अपवाद प्राप्त करना चाहिए जब आपके पास वास्तव में इसे संभालने की रणनीति हो - और लॉगिंग और रीथ्रोइंग "इसे संभालने" नहीं है। यदि आपके पास कोई सुधारात्मक कार्रवाई नहीं है, तो इसे विधि हस्ताक्षर में जोड़ने के लिए बेहतर है और इसे किसी ऐसे व्यक्ति को बुलबुला करने दें जो स्थिति को संभाल सके।

+15

मैं java.lang.Exception पकड़ने के बारे में भाग अलग तरीके से व्यक्त करने के लिए आप के लिए याचिका दायर कर सकते हैं? मुझे एहसास है कि यह एक उदाहरण है, लेकिन मुझे लगता है कि कुछ लोग इस जवाब को पढ़ सकते हैं और कह सकते हैं, "ओह, ठीक है, मैं बस अपवाद को पकड़ूंगा", जब संभवतः वह नहीं चाहता कि वे क्या करना चाहते हैं (या चाहिए)। –

+0

देखें कि यह बेहतर है या नहीं। – duffymo

+1

मुझे इसके बारे में पता था, लेकिन मैं इसे नहीं करना चाहता ... ओह, ठीक है, अनुमान है कि मैं जावा के अगले संस्करण तक 4 कैच के साथ फंस गया हूं ... – froadie

0

अपवाद को पकड़ें जो अपवाद पदानुक्रम में अभिभावक वर्ग होता है। This is of course, bad practice। आपके मामले में, सामान्य अभिभावक अपवाद अपवाद वर्ग होता है, और अपवाद का एक उदाहरण है जो किसी अपवाद को पकड़ता है, वास्तव में खराब अभ्यास है - नलपॉन्टरएक्सप्शन जैसे अपवाद आमतौर पर प्रोग्रामिंग त्रुटियां होती हैं और आमतौर पर शून्य मानों की जांच करके हल की जानी चाहिए।

11

यदि अपवादों का पदानुक्रम है तो आप अपवाद के सभी उप-वर्गों को पकड़ने के लिए बेस क्लास का उपयोग कर सकते हैं। पतित मामले में आप के साथ सभी जावा अपवाद पकड़ कर सकते हैं:

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

एक अधिक सामान्य मामले में अगर RepositoryException आधार वर्ग है और PathNotFoundException तो एक व्युत्पन्न वर्ग है:

try { 
    ... 
} catch (RepositoryException re) { 
    someCode(); 
} catch (Exception e) { 
    someCode(); 
} 

ऊपर कोड एक प्रकार के अपवाद हैंडलिंग के लिए RepositoryException और PathNotFoundException को पकड़ लेगा और अन्य सभी अपवाद एक साथ लम्बे हुए हैं। जावा 7 के बाद से, ऊपर @ OscarRyz के जवाब के अनुसार:

try { 
    ... 
} catch(IOException | SQLException ex) { 
    ... 
} 
+5

खंड BTW पकड़ने के क्रम में नियंत्रित किया जाता है: कोशिश { ... } पकड़ (अपवाद ई) { someCode(); } पकड़ें (रिपोजिटरी एक्सेप्शन पुनः) { // } –

+2

वास्तव में ठीक नहीं है क्योंकि यह कभी नहीं पहुंचा जा सकता है, ऐसे कोड संकलित भी नहीं होते हैं। – polygenelubricants

19

जावा 7 के भीतर आप जैसे कई कैच खंड को परिभाषित कर सकते हैं:

catch (IllegalArgumentException | SecurityException e) 
{ 
    ... 
} 
96

नहीं वास्तव में जावा 7 से पहले लेकिन, मैं कुछ इस तरह करना होगा :

जावा 6 और

try { 
    //..... 
} catch (Exception exc) { 
    if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
    exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException) { 

    someCode(); 

    } else if (exc instanceof RuntimeException) { 
    throw (RuntimeException) exc;  

    } else { 
    throw new RuntimeException(exc); 
    } 

} 
से पहले



जावा 7

try { 
    //..... 
} catch (IllegalArgumentException | SecurityException | 
     IllegalAccessException |NoSuchFieldException exc) { 
    someCode(); 
} 
+10

ध्यान दें कि आपका जावा 6 उदाहरण संकलक की क्षमता को तोड़ने की क्षमता को तोड़ देता है कि कहां से फेंक दिया जाएगा। – MichaelBlume

+1

@ माइकलब्लूम ट्रू, जो [इसलिए] बुरा नहीं है। आप हमेशा 'exc.getCause() 'के साथ मूल अपवाद प्राप्त कर सकते हैं। एक साइड नोट के रूप में, रॉबर्ट सी मार्टिन (दूसरों के बीच) अनचेक अपवादों का उपयोग करने की सिफारिश करता है (संकलक को पता नहीं है कि वहां से किस प्रकार का अपवाद फेंक दिया जाएगा); _Chapter 7 का संदर्भ लें: उसकी पुस्तक _Clean code_ पर त्रुटि हैंडलिंग_। – user454322

+2

आपके जावा 6 उदाहरण में आप एक नया अपवाद उदाहरण बनाने के बजाय मूल अपवाद को पुनर्स्थापित नहीं करना चाहिए, यानी 'नया रनटाइम अपवाद (एक्जी)' फेंकने के बजाय 'एक्सा' फेंकना चाहिए? –

6

एक क्लीनर (लेकिन कम वर्बोज़, और शायद के रूप में पसंदीदा नहीं) जावा 6 (यानी, Android) पर user454322 के जवाब देने के लिए विकल्प सभी Exception रों को पकड़ने और फिर से होगा फेंक RuntimeException एस। यह काम नहीं करेगा यदि आप स्टैक को आगे बढ़ाने के अन्य प्रकार के अपवादों को पकड़ने की योजना बना रहे हैं (जब तक कि आप उन्हें फिर से फेंक न दें), लेकिन चेक अपवादों को प्रभावी ढंग से पकड़ लेंगे।

उदाहरण के लिए:

try { 
    // CODE THAT THROWS EXCEPTION 
} catch (Exception e) { 
    if (e instanceof RuntimeException) { 
     // this exception was not expected, so re-throw it 
     throw e; 
    } else { 
     // YOUR CODE FOR ALL CHECKED EXCEPTIONS 
    } 
} 

कहा जा रहा है, शब्दाडंबर के लिए, यह सबसे अच्छा एक बूलियन या कुछ अन्य चर और कहा कि कोशिश कैच ब्लॉक के बाद कुछ कोड निष्पादित के आधार पर स्थापित करने के लिए हो सकता है।

+0

यह दृष्टिकोण संकलक को यह निर्धारित करने से रोकता है कि "कैच ब्लॉक" पहुंच योग्य होगा या नहीं। –

3

पूर्व 7 में कैसे करें के बारे:

Boolean caught = true; 
    Exception e; 
    try { 
    ... 
    caught = false; 
    } catch (TransformerException te) { 
    e = te; 
    } catch (SocketException se) { 
    e = se; 
    } catch (IOException ie) { 
    e = ie; 
    } 
    if (caught) { 
    someCode(); // You can reference Exception e here. 
    } 
+2

wuold एक अच्छा समाधान हो। 'आखिरकार' ब्लॉक में 'पकड़े गए' के ​​अंतिम नियंत्रण को कैसे सम्मिलित किया जाए? –

+0

इसे मूल प्रश्न की तुलना में अधिक लाइनों की आवश्यकता है। –

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