किसी फ़ंक्शन को कॉल करने के लिए "थ्रोस एक्सेप्शन" क्यों आवश्यक है?


97
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 बंद हो जाएगा। यह इसे अनदेखा करने के करीब है क्योंकि संकलक अनुमति देगा।
तैमूर

जब कहा जाता विधि ( Methdod1 ) फेंकता है Exception, हम बुला विधि (निर्धारित करने की Method2 के साथ) throws Exception; अगर हम कॉलिंग विधि में उस अपवाद को नहीं सौंप रहे हैं। इसका उद्देश्य Method2 की कॉलिंग विधि ( Method3 ) को सिर देना है, ताकि Method2 द्वारा एक अपवाद को फेंक दिया जा सके और आपको इसे यहां संभालना चाहिए, अन्यथा यह आपके प्रोग्राम को बाधित कर सकता है।
ऋतो

इसी तरह, अगर Method3 अपने शरीर में अपवाद को नहीं संभाल रहा है, तो उसे throws Exceptionअपनी कॉलिंग विधि को सिर देने के लिए इसकी विधि परिभाषा में परिभाषित करना होगा। पिछली टिप्पणी का विस्तार
Rito

जवाबों:


144

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

यहां छवि विवरण दर्ज करें

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


से जावा ट्यूटोरियल :

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

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

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

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

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

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

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


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

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

@ जोम्स - कहते हैं कि एक विधि के अंदर कोड IOException फेंकता है। फिर, विधि की घोषणा में "थ्रोस एक्ससेप्शन" डालना ठीक है?
मास्टरजोए

ओह। मुझे ये अब मिला। अपवाद पदानुक्रम के नियमों का अपवाद है। बनाता है। उत्तम। समझ। धन्यवाद जावा।
जेजेएस

25

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

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

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
        }
    }
}

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


7
सभी अपवाद जो उपवर्ग नहीं हैं RuntimeException, वह है।
यशवित

अगर अपवाद की तरह कोई अन्य वर्ग है जो जांचा जाता है?
nr5

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

अगर मैं कहूं कि चेक किए गए अपवादों को @ संकलन समय संभाला जाना चाहिए और रनटाइम पर पकड़ा जाना चाहिए। क्या मैं सही हू ? यदि हाँ, तो अनियंत्रित अपवाद के लिए एक ही वाक्य को फिर से बनाना होगा?
एनआर 5

@ jebar8 - आप जावा को .NET के साथ भ्रमित कर रहे हैं - जावा में, थ्रेशबल्स को विरासत में प्राप्त करना चाहिए Throwable(विरासत Exceptionभी काम करती है, क्योंकि यह विस्तारित होती है Throwable, लेकिन इसकी आवश्यकता नहीं है)।
BrainSlugs83

4

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


श्रृंखला में हर विधि मुख्य सहित अपवाद को फेंकने के लिए घोषित की जाती है। तो समस्या कहाँ है?
पॉल टॉम्बलिन

@PaTTomblin im पूछ रहा है कि कॉलिंग फ़ंक्शंस में थ्रो अपवाद लिखना क्यों आवश्यक है, एक फ़ंक्शन को कॉल करना जो एक अपवाद को फेंकता है
nr5

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

4

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

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

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

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

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

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


0
package javaexception;


public class JavaException {
   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[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

आपके कार्यक्रम में केवल छोटे परिवर्तन। यह मुख्य मुद्दे के बारे में कई लोगों द्वारा गलत समझा गया है, जब भी आप अपवाद को फेंकते हैं, तो आपको इसे संभालने की आवश्यकता होती है, उसी स्थान पर आवश्यक नहीं (उदाहरण के लिए, अपने कार्यक्रम में शो .1,2,3 विधि) लेकिन आपको पहले कॉलर विधि पर होना चाहिए। 'मुख्य' के अंदर। एक शब्द में, 'थ्रो' है, 'कैच / ट्राई' होना चाहिए, भले ही वही तरीका न हो जहां अपवाद होता है।


0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

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

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

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


0

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


इस टिप्पणी को टिप्पणी अनुभाग में जोड़ा जाना चाहिए क्योंकि यह एक सत्यापित उत्तर या एक का उदाहरण नहीं देता है। - stackoverflow.com/help/how-to-answer
पॉल डावसन

-1

मूल रूप से, यदि आप अपवाद को उसी स्थान पर नहीं संभाल रहे हैं जब आप इसे फेंक रहे हैं, तो आप फ़ंक्शन की परिभाषा में "थ्रो अपवाद" का उपयोग कर सकते हैं।

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