2014-08-27 3 views
5

जावा में हम एक खास प्रकार के अपवाद पकड़ कर सकते हैं:जावा एक अपवाद की पहचान ठीक

try{ 
    // Code that does IO like download a file... 
}catch(IOException ioe){ 
    ioe.printStackTrace(); 
    // handle ioe 
}catch(SomeOtherException soe){ 
    // handle soe 
} 

अब, वहाँ एक अपवाद बनाने के लिए कई कारणों से, इस मामले में, IOException हो सकता है कर सकते हैं:

java.io.IOException: Illegal character in path at index..... 
एक विशिष्ट पुस्तकालय या कुछ अन्य तरह से

:

java.io.IOException: Stream closed ... 

अगर कुछ गलत हो गया है Stream

अब, मेरा सवाल है, मैं कैसे निर्धारित करूं कि किस प्रकार का IOException हुआ?

मैं Stream closed और Illegal character in path at index... के बीच कैसे अंतर कर सकता हूं?

बेशक मैं केवल अपवाद संदेश की स्ट्रिंग की जांच कर सकता हूं लेकिन मुझे नहीं लगता कि यह अंतर्निहित लाइब्रेरी/कार्यान्वयन संदेश स्ट्रिंग को बदल सकता है क्योंकि यह सबसे अच्छा तरीका है।

संपादित करें:

e.getClass() इस मामले में लगभग सब कुछ के लिए रिटर्न java.io.IOException ...

मैं पुस्तकालय के लिए अपने स्वयं IOException फेंकता है, जबकि किसी भी मूल Exception की निकालने लगता है।

उत्तर

7

तथ्य यह है कि printStackTrace मुद्रित

java.io.IOException: Stream closed ... 
//  ^^^^^^^^^^^ 

और

java.io.IOException: Illegal character in path at index..... 
//  ^^^^^^^^^^^ 

मतलब है Exception प्रकार IOException की है। यहां एक और विशिष्ट उप प्रकार नहीं है जिसका आप यहां उपयोग कर सकते हैं।

इस मामले में कोई रास्ता नहीं है। उन्होंने उन कारणों के दोनों (और अधिक) के लिए उसी Exception प्रकार का उपयोग करने का निर्णय लिया। आप उन्हें विभिन्न catch कथनों से अलग करने में सक्षम नहीं होंगे। आपको अपना संदेश जांचना होगा।

यदि Exception में cause है, तो आपको यह देखना होगा कि क्या कोई विशिष्ट प्रकार है और इसे फिर से निकालना है। यदि आप भाग्यशाली हैं, तो आप Exception का एक और विशिष्ट प्रकार पकड़ने में सक्षम हो सकते हैं।

+2

मैंने आपको वापस ले लिया है क्योंकि यह एकमात्र उत्तर है जो 'IOEeception' को देखता है और जानता है कि यह एक ठोस प्रकार है। मुझे नहीं पता कि कोई आपको पहले स्थान पर क्यों गिराएगा ... – tom91136

+0

@ होवरक्राफ्टफुलऑफेल 'प्रिंटस्टैकट्रेस' विधि 'toString' विधि पर निर्भर करती है। 'थ्रोबल' कार्यान्वयन 'getClass()। GetName() 'के साथ वर्ग का नाम प्रिंट करता है। इसलिए जब तक 'StreamClosedException'' IOException' क्लास नाम को वापस करने के लिए अपने 'toString' को ओवरराइड नहीं करता है, तो ठोस प्रकार 'IOException' है। –

+0

@ सॉटिरियोसेलिमैनोलिस: क्षमा करें। –

4

आप अपवाद अलग ढंग से पकड़ कर सकते हैं के बाद से IOException उप अपवाद

के एक शीर्ष पदानुक्रम documentation से है:

java.io.IOException 
    java.io.CharConversionException 
    java.io.EOFException 
    java.io.FileNotFoundException 
    java.io.InterruptedIOException 
    java.io.ObjectStreamException 
     java.io.InvalidClassException 
     java.io.InvalidObjectException 
     java.io.NotActiveException 
     java.io.NotSerializableException 
     java.io.OptionalDataException 
     java.io.StreamCorruptedException 
     java.io.WriteAbortedException 
    java.io.SyncFailedException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
    java.io.UnsupportedEncodingException 
    java.io.UTFDataFormatException 
+1

ओपी के मामले में अपवादों का ठोस प्रकार 'IOException' प्रतीत होता है। अधिक विशिष्ट उपप्रकार मदद नहीं करेंगे। –

+0

हाँ, मैंने एक संपादन किया है कृपया अद्यतन प्रश्न की जांच करें – tom91136

1

जब एक पुस्तकालय एक भी सामान्य अपवाद (, के रूप में ऐसा लगता है को जन्म देती है, तो आप ' IOException के साथ यहां फिर से चल रहा है) दुर्भाग्य से आपके पास बहुत अच्छे विकल्प नहीं हैं - अनिवार्य रूप से यह लाइब्रेरी के हिस्से पर खराब डिज़ाइन है। आदर्श रूप से, आपको एक बग फाइल करना चाहिए या आपत्तिजनक पुस्तकालय के लिए पुल अनुरोध जमा करना चाहिए, लेकिन यह संभव या व्यवहार्य नहीं हो सकता है।

हालांकि सभी खो नहीं गए हैं। सबसे पहले और सबसे महत्वपूर्ण, यह संभव है कि लाइब्रेरी वास्तव में के माध्यम से अंतर्निहित कारण जेनेरिक IOException के साथ आपको अधिक जानकारी दे रही है। सामान्य हैंडलिंग के लिए एकल Exception को उजागर करते समय अधिक विस्तृत डिबगिंग जानकारी प्रदान करने का यह एक मजबूत तरीका है। इस पुस्तकालय में इस प्रथा का अनुसरण करता है, तो आप की तरह कुछ कर सकते हैं:

catch(IOException e) { 
    Throwable cause = e.getCause(); 
    if(cause != null && cause instanceof URISyntaxException) { 
    System.err.println("Bad URI"); 
    } else { 
    System.err.println("Other IOException"); 
    } 
} 

बेशक, मोड़ क्या कुछ Googling पता चलता है एक URISyntaxException एक IOException में पहली जगह में एक बहुत अच्छा डिजाइन नहीं है (गलत यूआरआई है निश्चित रूप से एक आईओ मुद्दा नहीं) इसलिए अगर मुझे लाइब्रेरी बस throw new IOException(e.getMessage()) जैसे कुछ कॉल कर रही है और मूल को छोड़कर आश्चर्यचकित नहीं होगी, दुर्भाग्यवश आपको जो कुछ भी करना है, वह अपवाद का संदेश है।

जैसा कि आप नोट करते हैं, अपवाद संदेशों को पार्स करना बहुत ही अच्छा विचार नहीं है। आदर्श रूप से, आपको इस खराब व्यवहार को एक सहायक विधि में लपेटना चाहिए ताकि लाइब्रेरी में सुधार हो जाने के बाद आप आसानी से इसे पुनः प्रतिक्रिया दे सकें, और पता लगाए कि कुछ अप्रत्याशित होता है और उसे संबोधित करता है। पर विचार करें:

public void doOperation(arguments) throws IOException, URISyntaxException { 
    try { 
    BadLibrary.doOperation(arguments); 
    } catch(IOException e) { 
    if(e.getMessage().startsWith("Illegal character")) { 
     throw new URISyntaxException("Uknown", e.getMessage()); 
    } else if(e.getMessage().startsWith("Stream closed")) { 
     throw e; 
    } else { 
     // note we include the cause here 
     throw new RuntimeException("Unexpected exception from BadLibrary", e); 
    } 
    } 
} 
इस compartmentalization आप केवल एक ही स्थान पर इस अप्रिय जांच करना है के साथ

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

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