2010-07-13 16 views
94

क्या ये कोड कथन समकक्ष हैं? क्या उनके बीच कोई अंतर है?कोशिश/पकड़ बनाम फेंकता अपवाद

private void calculateArea() throws Exception { 
     ....do something 
    } 

private void calculateArea() { 
     try { 
      ....do something 

     } catch (Exception e) { 
      showException(e); 
     } 
    } 
+2

नहीं वास्तव में एक जवाब है, लेकिन आप में नेड Batchelder के लेख [अपवाद रुचि हो सकती है रेनफोरेस्ट में] (http://nedbatchelder.com/text/exceptions-in-the-rainforest.html), जो सामान्य मामलों की व्याख्या करने में मदद करता है जहां एक शैली या दूसरे को प्राथमिकता दी जानी चाहिए। पकड़ में "शोएक्सप्शन (ई)" रखने के बजाय –

+1

, क्या आप पूछ रहे थे कि क्या आपने पकड़ में "फेंकता है" (या कोशिश/पकड़ नहीं है)? – MacGyver

उत्तर

116

हाँ, वहाँ एक बहुत बड़ा अंतर है - उत्तरार्द्ध स्वैलोज़ अपवाद (यह दिखा, बेशक), जबकि पहले एक यह प्रचार करने देगा। (मुझे लगता है कि showException इसे पुनर्स्थापित नहीं करता है।)

तो यदि आप पहली विधि को कॉल करते हैं और "कुछ करें" विफल रहता है, तो कॉलर को अपवाद को संभालना होगा। यदि आप दूसरी विधि को कॉल करते हैं और "कुछ करें" विफल रहता है, तो कॉलर को बिल्कुल अपवाद नहीं दिखाई देगा ... जो आमतौर पर एक बुरी चीज है, जब तक showExceptionवास्तविक रूप से अपवाद को संभाला, जो भी गलत था, और आम तौर पर सुनिश्चित किया जाता है कि calculateArea ने अपना उद्देश्य हासिल कर लिया है।

आप इस बताने के लिए है, क्योंकि आप या तो पकड़ने Exception खुद या घोषणा की कि अपने विधि यह भी फेंक सकती है बिना पहली विधि कॉल नहीं कर सकते कर सकते हैं।

+10

जब आप उल्लेख करते हैं कि "जब तक यह वास्तव में अपवाद को संभाला नहीं जाता", यह एक अच्छा बिंदु है। मैंने सोचा कि मैं जोड़ता हूं कि "अपवाद" पकड़ने से ही वह शायद ही कभी वास्तविक अपवाद के बुद्धिमान "हैंडलिंग" की ओर जाता है, यही कारण है कि लोग आपको सबसे विशिष्ट अपवाद को पकड़ने की सलाह देते हैं। –

+16

+1।क्योंकि जॉन स्कीट को और अधिक प्रतिष्ठा की आवश्यकता है। ओह, और जवाब भी अच्छा था। –

13

हां। संस्करण जो throws Exception घोषित करता है उसे अपवाद को संभालने के लिए कॉलिंग कोड की आवश्यकता होगी, जबकि संस्करण जो स्पष्ट रूप से इसे संभालता है, वह नहीं होगा।

अर्थात, बस:

performCalculation(); 

बनाम फोन करने वाले के लिए अपवाद हैंडलिंग का बोझ बढ़ रहा है:

try { 
    performCalculation(); 
catch (Exception e) { 
    // handle exception 
} 
11

पहले एक throws Exception, तो फोन करने वाले Exception संभाल करने की जरूरत है। दूसरा एक आंतरिक रूप से Exception को पकड़ता है और संभालता है, इसलिए कॉलर को कोई अपवाद हैंडलिंग नहीं करना पड़ता है।

+0

तो संक्षेप में, मुझे हमेशा दूसरे का उपयोग करना चाहिए। क्या मैं सही हू? पहला वास्तव में एक विधि है जिसका प्रयोग प्रोग्राम के विभिन्न बिंदुओं में किया जाता है। यही कारण है कि मैंने आगे के उपयोग के लिए निर्देशों को इकट्ठा करने का फैसला किया लेकिन ऐसा करने के बाद अब मुझे एहसास हुआ कि टी बड़ी गलती कर रहा है .. – carlos

+7

नहीं, दोनों पैटर्न की आवश्यकता है। यदि आपकी विधि अपवाद को संभाल सकती है, तो दूसरे पैटर्न का उपयोग करें, यदि नहीं, तो कॉलर को नोटिफ़ाई करने के लिए पहले व्यक्ति का उपयोग करें। –

+0

आप जिस संस्करण का उपयोग करते हैं वह आपकी आवश्यकताओं पर निर्भर करता है - मूल रूप से उस अपवाद को संभालने के लिए आपको किस स्तर पर आवश्यकता होती है। कॉलर को तदनुसार कोड किया जाना चाहिए। यदि कोई कॉलर पहले संस्करण को कॉल कर रहा था, और आप विधि संस्करण को दूसरे संस्करण के साथ प्रतिस्थापित करते हैं, तो आपके कॉलर कोड को अपवाद को संभालने के लिए मजबूर किया जाएगा क्योंकि यह एक चेक अपवाद है। – samitgaur

4

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

आम तौर पर भी बोलते हुए, आप एक सामान्य अपवाद नहीं पकड़ना चाहते हैं। इसके बजाए, आप केवल विशिष्ट विशेषताओं को पकड़ना चाहेंगे, जैसे FileNotFoundException या IOException क्योंकि वे अलग-अलग चीजों का अर्थ ले सकते हैं।

1

मुझे लगता है कि "समान" द्वारा आप व्यवहार का जिक्र कर रहे हैं।

1) दिए गए मान

2) फेंका अपवाद

3) दुष्प्रभाव (i:

एक समारोह का एक व्यवहार द्वारा निर्धारित किया जा सकता है।ई ढेर, फाइल सिस्टम इत्यादि में परिवर्तन)

इस मामले में, पहली विधि किसी भी अपवाद को फैलती है, जबकि दूसरी कोई जांच अपवाद नहीं फेंकता है, और अनचेक अपवादों के साथ-साथ अधिकांश निगल भी जाता है, इसलिए व्यवहार अलग है।

हालांकि, अगर आप की गारंटी है कि "कुछ करना" फेंकता है कभी नहीं एक अपवाद है, तो व्यवहार समान होगा (हालांकि संकलक पहले संस्करण में, अपवाद को संभालने के लिए फोन करने वाले की आवश्यकता होगी)

--edit -

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

3

एक विशेष परिदृश्य है जहां हम फेंकने का उपयोग नहीं कर सकते हैं, हमें कोशिश-पकड़ का उपयोग करना होगा। एक नियम है "एक ओवरराइड विधि उसके माता-पिता वर्ग को फेंकने के अलावा कोई अतिरिक्त अपवाद नहीं फेंक सकता है"। यदि कोई अतिरिक्त अपवाद है जिसे ट्राइक-कैच का उपयोग करके संभाला जाना चाहिए। इस कोड स्निपेट पर विचार करें। एक सरल आधार वर्ग

package trycatchvsthrows; 

public class Base { 
    public void show() 
    { 
     System.out.println("hello from base"); 
    } 
} 

नहीं है और यह वर्ग व्युत्पन्न है:

package trycatchvsthrows; 

public class Derived extends Base { 

    @Override 
    public void show() { 
     // TODO Auto-generated method stub 
     super.show(); 

     Thread thread= new Thread(); 
     thread.start(); 
     try { 
      thread.sleep(100); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     // thread.sleep(10); 
     // here we can not use public void show() throws InterruptedException 
     // not allowed 
    } 
} 

हम Thread.Sleep कॉल करने के लिए() हम कोशिश-पकड़ का उपयोग करने के लिए मजबूर कर रहे हैं है, तो यहाँ हम उपयोग नहीं कर सकते :

public void show() throws InterruptedException 

क्योंकि ओवरराइड विधि अतिरिक्त अपवाद नहीं फेंक सकती है।

+0

मुझे विश्वास है कि हर किसी को इस चेतावनी के बारे में पता नहीं है। अच्छी तरह से इशारा किया। – ivanleoncz

0

इस विधि के कॉलर को या तो इस अपवाद को पकड़ने की आवश्यकता होगी या इसे इसके विधि हस्ताक्षर में पुनर्स्थापित करने की घोषणा की जाएगी।

private void calculateArea() throws Exception { 
     // Do something 
    } 

नीचे प्रयास करें ब्लॉक उदाहरण में। इस विधि के कॉलर को अपवाद को संभालने के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि इसकी पहले से ही देखभाल की जा चुकी है।

private void calculateArea() { 
    try { 
     // Do something 

    } catch (Exception e) { 
     showException(e); 
    } 
} 
0

कई बार आप कॉलर अपवाद को संभालने के लिए चाहते हैं। आइए मान लें कि आपके पास कॉलर एक विधि है जिसे एक और विधि कहा जाता है जो प्रत्येक विधि को अपवाद को संभालने के बजाय दूसरी विधि कहता है, आप इसे कॉलर पर ही संभाल सकते हैं। जब तक कि आप उस विधि में विफल होने पर किसी भी तरीके से कुछ नहीं करना चाहते हैं।

1

आप एक अपवाद फेंक दिया है, तो बच्चे को विधि (जो इस ओवरराइड करता है) अपवाद

उदाहरण संभाल चाहिए:

class A{ 
public void myMethod() throws Exception{ 
//do something 
} 
} 

A a=new A(); 
try{ 
a.myMethod(); 
}catch Exception(e){ 
//handle the exception 
} 
संबंधित मुद्दे