49
class throwseg1 
{ 
    void show() throws Exception 
    { 
     throw new Exception("my.own.Exception"); 
    } 

    void show2() throws Exception // Why throws is necessary here ? 
    { 
     show(); 
    } 

    void show3() throws Exception // Why throws is necessary here ? 
    { 
     show2(); 
    } 

    public static void main(String s[]) throws Exception // Why throws is necessary here ? 
    { 
     throwseg1 o1 = new throwseg1(); 
     o1.show3(); 
    } 
} 

संकलक क्यों की रिपोर्ट है कि तरीकों show2(), show3(), और main() हैफ़ंक्शन को कॉल करते समय "अपवाद फेंकना" क्यों आवश्यक है?

असूचित अपवाद अपवाद है कि पकड़े जाने या घोषित किया जाना चाहिए फेंक दिया करने के लिए

जब मैं इन तरीकों से throws Exception निकालना चाहते हैं?

+2

@PaulTomblin मुख्य निश्चित रूप से अपवाद को फेंकने के लिए घोषित किया जा सकता है। यदि ऐसा होता है, तो JVM बंद हो जाएगा। यह अनदेखा करने के करीब है क्योंकि संकलक अनुमति देगा। – Taymon

+0

जब कॉल की गई विधि (** मेथडोड 1 **) 'अपवाद' फेंकता है, तो हमें 'थ्रो अपवाद' के साथ कॉलिंग विधि (** विधि 2 **) को परिभाषित करना होगा; अगर हम कॉलिंग विधि में उस अपवाद को सौंप नहीं रहे हैं। इसका उद्देश्य ** विधि 2 ** के कॉलिंग विधि (** विधि 3 **) तक सिर देना है कि एक अपवाद ** विधि 2 ** द्वारा फेंक दिया जा सकता है और आपको इसे यहां संभालना चाहिए, अन्यथा यह आपके बाधित हो सकता है कार्यक्रम। – Rito

+0

इसी प्रकार, यदि ** विधि 3 ** अपने शरीर में अपवाद को संभाल नहीं रहा है, तो उसे अपनी विधि परिभाषा में 'अपवाद' फेंकना था ताकि उसकी कॉलिंग विधि को आगे बढ़ाया जा सके। पिछली टिप्पणी का _extension_ – Rito

उत्तर

90

जावा में, जैसा कि आप जानते हैं, अपवादों को दो में वर्गीकृत किया जा सकता है: एक जिसे throws खंड की आवश्यकता है या यदि आप एक और दूसरे को निर्दिष्ट नहीं करते हैं तो उसे संभाला जाना चाहिए। अब, निम्न चित्र देखें:

enter image description here

जावा में, आप कुछ भी है कि Throwable वर्ग फैली फेंक कर सकते हैं। हालांकि, आपको सभी कक्षाओं के लिए throws खंड निर्दिष्ट करने की आवश्यकता नहीं है। विशेष रूप से, कक्षाएं जो Error या RuntimeException या इनमें से किसी भी उप-वर्ग हैं। आपके मामले में ExceptionError या RuntimeException का उप-वर्ग नहीं है। इसलिए, यह एक चेक अपवाद है और throws खंड में निर्दिष्ट होना चाहिए, यदि आप उस विशेष अपवाद को संभाल नहीं पाते हैं। यही कारण है कि आपको throws खंड की आवश्यकता है।


Java Tutorial से:

एक अपवाद की एक घटना है, जो एक कार्यक्रम है, कि इस कार्यक्रम के निर्देशों के सामान्य प्रवाह बाधित के निष्पादन के दौरान होता है।

अब, जैसा कि आप जानते हैं कि अपवादों को दो में वर्गीकृत किया गया है: चेक और अनचेक किया गया। इन वर्गीकरण क्यों?

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

अनचेक अपवाद: उन्हें फिर से दो में विभाजित किया जा सकता है: त्रुटियां और रनटाइम अपवाद। उनके लिए अनचेक करने का एक कारण यह है कि वे संख्या में असंख्य हैं, और उन सभी को संभालने के लिए आवश्यक है जो हमारे प्रोग्राम को अव्यवस्थित करेंगे और इसकी स्पष्टता को कम करेंगे। अन्य कारण है:

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

  • त्रुटियां: त्रुटियां ऐसी स्थितियां हैं जिनसे आमतौर पर प्रोग्राम पुनर्प्राप्त नहीं हो सकता है। उदाहरण के लिए, यदि StackOverflowError होता है, तो हमारा प्रोग्राम अधिक नहीं कर सकता है, जैसे प्रोग्राम के फ़ंक्शन कॉलिंग स्टैक के आकार को बढ़ाएं। या यदि OutOfMemoryError होता है, तो हम अपने कार्यक्रम में उपलब्ध रैम की मात्रा बढ़ाने के लिए बहुत कुछ नहीं कर सकते हैं। ऐसे मामलों में, कार्यक्रम से बाहर निकलना बेहतर है। यही कारण है कि वे अनचेक किए गए हैं।

विस्तृत जानकारी के लिए देखें:

+0

जो मुझे आपके उत्तर से मिला वह यह है कि त्रुटि वर्ग और इसके sublaclasses और runtimeException वर्ग और इसके उप वर्ग, वे अनचेक अपवाद के तहत आते हैं (जैसे System.out.println (5/0); इसके रूप में फेंकने की कोई आवश्यकता नहीं है एक रनटाइम अपवाद है लेकिन फिर भी हम कोशिश पकड़ने के लिए आवेदन कर सकते हैं) और अपवाद वर्ग की जांच की गई है, इसलिए हमें उस विधि में फेंकता खंड घोषित करने की आवश्यकता है और प्रत्येक विधि जो इसे – Nil

+0

@ rd4code कहती है या हमें उन्हें 'कोशिश करें ... पकड़' के साथ संभालना होगा। – Jomoos

+0

एक और प्रश्न: यदि अपवादों को संकलित समय के दौरान अधिक संख्या में त्रुटियों से बचने के लिए अनचेक किए गए और चेक किए गए, विशेष रूप से अनचेक वाले (रनटाइम त्रुटियों) में वर्गीकृत किया गया है? – Nil

3

Exception एक चेक अपवाद वर्ग है। इसलिए, कोई भी कोड जो एक विधि को कॉल करता है जो घोषणा करता है कि यह throws Exception को इसे संभाल या घोषित करना होगा।

+0

चेन में प्रत्येक विधि को मुख्य सहित अपवाद फेंकने के लिए घोषित किया जाता है। तो समस्या कहां है? –

+0

@PaulTomblin मैं यह पूछ रहा हूं कि कॉलिंग फ़ंक्शंस में फेंकने के लिए जरूरी क्यों है, एक फ़ंक्शन को कॉल करना जो अपवाद फेंकता है – Nil

+0

ठीक है, मुझे समझ में नहीं आया कि आप एक कंपाइलर त्रुटि के बारे में क्यों पूछ रहे थे जिसे आप वास्तव में नहीं प्राप्त कर रहे थे आपके द्वारा पोस्ट किए गए कोड से। यह पूछने का एक अजीब तरीका है। –

18

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

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

class throwseg1 { 
    void show() throws Exception { 
     throw new Exception(); 
    } 
} 

के रूप में लिखा जाना चाहिए:

class throwseg1 { 
    void show() { 
     try { 
      throw new Exception(); 
     } catch(Exception e) { 
      // code to handle the exception 
     } 
    } 
} 

इस तरह आप "फेंकता अपवाद" विधि घोषणा में घोषणा से छुटकारा पा सकते।

+3

सभी अपवाद जो 'RuntimeException' के उप-वर्ग नहीं हैं, जो है। – yshavit

+0

यदि कोई अन्य वर्ग है जो अपवाद की तरह है? – Nil

+1

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

3

throws Exception घोषणा उन तरीकों का ट्रैक रखने का एक स्वचालित तरीका है जो अनुमानित लेकिन अपरिहार्य कारणों के लिए अपवाद फेंक सकते हैं। घोषणा आमतौर पर प्रकार या अपवादों के प्रकारों के बारे में विशिष्ट होती है जिन्हें throws IOException या throws IOException, MyException जैसे फेंक दिया जा सकता है।

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

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

हालांकि जावा में अपवाद घोषित करने की क्षमता है, फिर भी आप अनचाहे और अविकसित अपवादों के साथ एक नई विधि लिख सकते हैं, और जावा इसे संकलित करेगा और आप इसे चला सकते हैं और सर्वश्रेष्ठ के लिए आशा कर सकते हैं। जावा आपको ऐसा करने की अनुमति नहीं देगा यदि यह ऐसी विधि का उपयोग करता है जिसे फेंकने वाले अपवाद के रूप में घोषित किया गया है, जब तक कि आप या तो अपनी विधि में घोषित अपवादों को संभाल न लें या अपनी विधि को फेंकने के रूप में घोषित न करें अपवाद (ओं) या यदि कई अपवाद हैं, तो आप कुछ को संभाल सकते हैं और बाकी को फेंक सकते हैं।

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

इस प्रकार के समाधान के बारे में अच्छी बात यह है कि जब संकलक Error: Unhandled exception type java.io.IOException रिपोर्ट करता है तो यह अपवाद फेंकने के लिए घोषित विधि की फ़ाइल और लाइन संख्या देता है। इसके बाद आप बस हिरण पास करना चुन सकते हैं और अपनी विधि को "IOException फेंकता है" घोषित कर सकते हैं। यह मुख्य विधि तक सभी तरह से किया जा सकता है, जहां यह प्रोग्राम को रोकने और उपयोगकर्ता के अपवाद की रिपोर्ट करने का कारण बनता है। हालांकि, अपवाद को पकड़ना और इसके साथ सौदा करना बेहतर होता है जैसे कि उपयोगकर्ता को समझाया गया है कि यह क्या हुआ है और इसे कैसे ठीक किया जाए। जब कोई विधि अपवाद को पकड़ती है और संभालती है, तो इसे अब अपवाद घोषित नहीं करना पड़ता है। बकवास बोलने के लिए वहां रुक जाता है।