जावा विधि घोषणा में फेंकता का उपयोग कब करें?


82

इसलिए मैंने सोचा कि मुझे जावा में अपवाद-संचालन की एक अच्छी बुनियादी समझ थी, लेकिन मैं हाल ही में कुछ कोड पढ़ रहा था जिससे मुझे कुछ भ्रम और संदेह हुआ। मेरा मुख्य संदेह जो मैं यहाँ संबोधित करना चाहता हूं, वह यह है कि किसी व्यक्ति को जावा विधि घोषणा में फेंकता का उपयोग निम्न तरह से करना चाहिए:

    public void method() throws SomeException
    {
         // method body here
    }

कुछ इसी तरह की पोस्ट पढ़ से मुझे लगता है कि इकट्ठा फेंकता घोषणा के एक प्रकार के रूप में प्रयोग किया जाता है SomeException विधि के निष्पादन के दौरान फेंक दिया जा सकता है।

मेरा भ्रम कुछ कोड से आता है जो इस तरह दिखता है:

     public void method() throws IOException
     {
          try
          {
               BufferedReader br = new BufferedReader(new FileReader("file.txt"));
          }
          catch(IOException e)
          {
               System.out.println(e.getMessage());
          }
     }

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

जवाबों:


79

यदि आप एक अपवाद प्रकार को पकड़ रहे हैं, तो आपको इसे फेंकने की आवश्यकता नहीं है, जब तक कि आप इसे पुनर्विचार करने नहीं जा रहे हैं। आपके द्वारा पोस्ट किए जाने वाले उदाहरण में, डेवलपर को एक या दूसरे को करना चाहिए, दोनों को नहीं।

आमतौर पर, यदि आप अपवाद के साथ कुछ नहीं करने जा रहे हैं, तो आपको इसे नहीं पकड़ना चाहिए।

सबसे खतरनाक चीज जो आप कर सकते हैं वह एक अपवाद को पकड़ना है और इसके साथ कुछ भी नहीं करना है।

अपवादों को फेंकना कब उचित है इसकी एक अच्छी चर्चा यहाँ है

अपवाद कब फेंकना है?


2
विधि हस्ताक्षर में अनियंत्रित अपवादों को भी 'थ्रो' के साथ घोषित किया जाना चाहिए, या क्या केवल चेक किए गए अपवादों के लिए 'थ्रो' का उपयोग करना अभ्यास है?
कोड़ी

यह उत्तर सीधे प्रश्न के केंद्रीय पहलू को संबोधित नहीं करता है: throwsकीवर्ड का उपयोग ।
ब्रेंट बर्नबर्न

@hvgotcodes क्या होता है अगर मैं एक अपवाद को पकड़ता हूं और कुछ भी नहीं करता हूं?
मनोज ५

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

22

आपको केवल एक विधि पर एक थ्रो क्लॉज़ शामिल करने की आवश्यकता है यदि विधि एक चेक अपवाद फेंकता है। यदि विधि रनटाइम अपवाद को फेंकती है तो ऐसा करने की कोई आवश्यकता नहीं है।

चेक किए गए बनाम विचलित अपवादों पर कुछ पृष्ठभूमि के लिए यहां देखें: http://download.oracle.com/javase/tutorial/essential/exception/runtime.html

यदि विधि अपवाद को पकड़ती है और इससे आंतरिक रूप से निपटती है (जैसा कि आपके दूसरे उदाहरण में है) तो थ्रो क्लॉज़ को शामिल करने की कोई आवश्यकता नहीं है।


9

आपके द्वारा देखा गया कोड आदर्श नहीं है। आपको या तो:

  1. अपवाद को पकड़ो और इसे संभालो; किस मामले में throwsअप्राकृतिक है।

  2. निकालें try/catch; जिस स्थिति में अपवाद को कॉलिंग विधि द्वारा नियंत्रित किया जाएगा।

  3. अपवाद को पकड़ें, संभवतः कुछ कार्रवाई करें और फिर अपवाद को हटा दें (केवल संदेश नहीं)


2

आप सही हैं, उस उदाहरण में throwsयह शानदार है। यह संभव है कि इसे पिछले कुछ कार्यान्वयन से वहां छोड़ दिया गया था - शायद अपवाद को मूल रूप से कैच ब्लॉक में पकड़े जाने के बजाय फेंक दिया गया था।


2

आपके द्वारा पोस्ट किया गया कोड गलत है, यह एक अपवाद को फेंकना चाहिए यदि हैंडलर IOException के लिए एक विशिष्ट अपवाद को पकड़ रहा है लेकिन अपवाद नहीं पकड़ा गया है।

कुछ इस तरह:

public void method() throws Exception{
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println(e.getMessage());
   }
}

या

public void method(){
   try{
           BufferedReader br = new BufferedReader(new FileReader("file.txt"));
   }catch(IOException e){
           System.out.println("Catching IOException");
           System.out.println(e.getMessage());
   }catch(Exception e){
           System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc.");
           System.out.println(e.getMessage());
   }

}


1

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


1

यह एक उत्तर नहीं है, लेकिन एक टिप्पणी है, लेकिन मैं एक प्रारूपित कोड के साथ एक टिप्पणी नहीं लिख सकता था, इसलिए यहां टिप्पणी है।

कहते हैं कि वहाँ है

public static void main(String[] args) {
  try {
    // do nothing or throw a RuntimeException
    throw new RuntimeException("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

आउटपुट है

test
Exception in thread "main" java.lang.RuntimeException: test
    at MyClass.main(MyClass.java:10)

यह विधि किसी भी "फेंकता" अपवाद की घोषणा नहीं करती है, लेकिन उन्हें फेंक देती है! चाल यह है कि फेंके गए अपवाद RuntimeException (अनियंत्रित) हैं जिन्हें विधि पर घोषित करने की आवश्यकता नहीं है। यह विधि के पाठक के लिए थोड़ा भ्रामक है, क्योंकि वह जो भी देखती है वह "फेंक ई;" बयान लेकिन फेंकता अपवाद की कोई घोषणा नहीं

अब, अगर हमारे पास है

public static void main(String[] args) throws Exception {
  try {
    throw new Exception("test");
  } catch (Exception e) {
    System.out.println(e.getMessage());
    throw e;
  }
}

हमें विधि में "थ्रो" अपवाद घोषित करना होगा अन्यथा हमें एक संकलक त्रुटि मिलती है।


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