1. अपवादों के प्रकार

अपवादों के प्रकार

सभी अपवादों को 4 प्रकारों में विभाजित किया गया है, जो वास्तव में वे वर्ग हैं जो एक दूसरे को विरासत में देते हैं।

Throwableकक्षा

सभी अपवादों के लिए आधार वर्ग वर्ग है Throwableकक्षा Throwableमें वह कोड होता है जो वर्तमान कॉल स्टैक (वर्तमान विधि का स्टैक ट्रेस) को सरणी में लिखता है। हम थोड़ी देर बाद सीखेंगे कि स्टैक ट्रेस क्या होता है।

फेंक ऑपरेटर केवल उस वस्तु को स्वीकार कर सकता है जो कक्षा से प्राप्त होती है Throwableऔर यद्यपि आप सैद्धांतिक रूप से कोड लिख सकते हैं throw new Throwable();, आमतौर पर कोई भी ऐसा नहीं करता है। कक्षा का मुख्य उद्देश्य Throwableसभी अपवादों के लिए एकल अभिभावक वर्ग होना है।

Errorकक्षा

अगला अपवाद वर्ग वह Errorवर्ग है, जो सीधे Throwableवर्ग को इनहेरिट करता है। गंभीर समस्या होने पर जावा मशीन Errorवर्ग (और उसके वंश) की वस्तुओं का निर्माण करती है । उदाहरण के लिए, एक हार्डवेयर खराबी, अपर्याप्त मेमोरी, आदि।

आमतौर पर, एक प्रोग्रामर के रूप में, ऐसी स्थिति में आप कुछ नहीं कर सकते हैंError जहां प्रोग्राम में ऐसी त्रुटि (जिस प्रकार के लिए a को फेंका जाना चाहिए) हो: ये त्रुटियां बहुत गंभीर हैं। आप केवल इतना कर सकते हैं कि उपयोगकर्ता को सूचित करें कि प्रोग्राम क्रैश हो रहा है और/या प्रोग्राम लॉग में त्रुटि के बारे में सभी ज्ञात जानकारी लिखें।

Exceptionकक्षा

और कक्षाएं सामान्य त्रुटियों के लिए हैं जो बहुत सारी विधियों Exceptionके RuntimeExceptionसंचालन में होती हैं। प्रत्येक फेंके गए अपवाद का लक्ष्य एक ऐसे catchब्लॉक द्वारा पकड़ा जाना है जो जानता है कि इसे ठीक से कैसे संभालना है।

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

दूसरे शब्दों में, यदि एक चर के बराबर है null, तो विधि एक फेंक देगी NullPointerException। यदि गलत तर्क विधि को पारित किए गए थे, तो यह एक फेंक देगा InvalidArgumentException। यदि विधि गलती से शून्य से विभाजित हो जाती है, तो यह एक फेंक देगी ArithmeticException

RuntimeExceptionकक्षा

RuntimeExceptionsका उपसमुच्चय हैं Exceptions। हम यह भी कह सकते हैं कि RuntimeExceptionयह सामान्य अपवादों ( ) का हल्का संस्करण है Exception— ऐसे अपवादों पर कम आवश्यकताएं और प्रतिबंध लगाए जाते हैं

Exceptionआप और RuntimeExceptionबाद में अंतर सीखेंगे ।


2. Throws: चेक किए गए अपवाद

फेंकता है: चेक किए गए अपवाद

सभी जावा अपवाद 2 श्रेणियों में आते हैं: चेक किए गए और अनचेक किए गए

सभी अपवाद जो इनहेरिट करते हैं RuntimeExceptionया अनियंत्रित अपवादError माने जाते हैं । अन्य सभी चेक किए गए अपवाद हैं ।

महत्वपूर्ण!

चेक किए गए अपवादों को पेश किए जाने के बीस साल बाद, लगभग हर जावा प्रोग्रामर इसे एक बग के रूप में सोचता है। लोकप्रिय आधुनिक रूपरेखाओं में, सभी अपवादों में से 95% अनियंत्रित हैं। सी # भाषा, जिसने लगभग जावा की नकल की, चेक किए गए अपवादों को नहीं जोड़ा ।

जाँचे गए और अनियंत्रित अपवादों के बीच मुख्य अंतर क्या है ?

चेक किए गए अपवादों पर अतिरिक्त आवश्यकताएं लगाई गई हैं । मोटे तौर पर, वे ये हैं:

आवश्यकता 1

यदि कोई विधि चेक किए गए अपवाद को फेंकती है , तो उसे अपने हस्ताक्षर में अपवाद के प्रकार को इंगित करना चाहिएइस तरह, इसे कॉल करने वाली हर विधि को पता है कि इसमें "सार्थक अपवाद" हो सकता है।

कीवर्ड के बाद विधि पैरामीटर के बाद चेक किए गए अपवादों को इंगित करें ( गलती से कीवर्ड का उपयोग न करें )। ऐसा कुछ दिखता है:throwsthrow

type method (parameters) throws exception

उदाहरण:

जाँच अपवाद अनियंत्रित अपवाद
public void calculate(int n) throws Exception
{
   if (n == 0)
      throw new Exception("n is null!");
}
public void calculate(n)
{
   if (n == 0)
      throw new RuntimeException("n is null!");
}

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

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

public void calculate(int n) throws Exception, IOException
{
   if (n == 0)
      throw new Exception("n is null!");
   if (n == 1)
      throw new IOException("n is 1");
}

आवश्यकता 2

यदि आप किसी ऐसे तरीके को कॉल करते हैं जिसने अपने हस्ताक्षर में अपवादों की जांच की है , तो आप इस तथ्य को अनदेखा नहीं कर सकते कि यह उन्हें फेंकता है।

catchआपको या तो ऐसे सभी अपवादों को हर एक के लिए ब्लॉक जोड़कर , या उन्हेंthrows अपनी विधि के लिए एक खंड में जोड़कर पकड़ना होगा।

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

उदाहरण:

कल्पना कीजिए कि हम मनुष्यों द्वारा आबाद दुनिया बनाने के लिए एक विधि लिख रहे हैं। लोगों की प्रारंभिक संख्या को एक तर्क के रूप में पारित किया जाता है। इसलिए अगर बहुत कम लोग हैं तो हमें अपवाद जोड़ने की जरूरत है।

पृथ्वी का निर्माण टिप्पणी
public void createWorld(int n) throws EmptyWorldException, LonelyWorldException
{
   if (n == 0)
      throw new EmptyWorldException("There are no people!");
   if (n == 1)
      throw new LonelyWorldException ("There aren't enough people!");
   System.out.println("A wonderful world was created. Population: " + n);
}
विधि संभावित रूप से दो चेक किए गए अपवादों को फेंकती है:

  • EmptyWorldException
  • अकेला विश्व अपवाद

इस विधि कॉल को 3 तरीकों से नियंत्रित किया जा सकता है:

1. कोई अपवाद न पकड़ें

यह अक्सर तब किया जाता है जब विधि को यह नहीं पता होता है कि स्थिति को ठीक से कैसे संभालना है।

कोड टिप्पणी
public void createPopulatedWorld(int population)
throws EmptyWorldException, LonelyWorldException
{
   createWorld(population);
}
कॉलिंग विधि अपवादों को नहीं पकड़ती है और दूसरों को उनके बारे में सूचित करना चाहिए: यह उन्हें अपने throwsखंड में जोड़ता है

2. कुछ अपवादों को पकड़ें

हम उन त्रुटियों को संभालते हैं जिन्हें हम संभाल सकते हैं। लेकिन जिन्हें हम समझ नहीं पाते, हम उन्हें कॉलिंग मेथड तक फेंक देते हैं। ऐसा करने के लिए, हमें उनका नाम थ्रो क्लॉज में जोड़ना होगा:

कोड टिप्पणी
public void createNonEmptyWorld(int population)
throws EmptyWorldException
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
}
कॉलर केवल एक चेक किए गए अपवाद को पकड़ता है — LonelyWorldException. अन्य अपवाद को इसके हस्ताक्षर में जोड़ा जाना चाहिए, जो इसे throwsकीवर्ड के बाद दर्शाता है

3. सभी अपवादों को पकड़ें

यदि विधि कॉलिंग विधि के अपवादों को नहीं फेंकती है, तो कॉलिंग विधि हमेशा आश्वस्त रहती है कि सब कुछ अच्छी तरह से काम करता है। और यह असाधारण स्थितियों को ठीक करने के लिए कोई कार्रवाई करने में असमर्थ होगा।

कोड टिप्पणी
public void createAnyWorld(int population)
{
   try
   {
      createWorld(population);
   }
   catch (LonelyWorldException e)
   {
      e.printStackTrace();
   }
   catch (EmptyWorldException e)
   {
      e.printStackTrace();
   }
}
इस विधि में सभी अपवाद पकड़े जाते हैं। फोन करने वाले को विश्वास हो जाएगा कि सब ठीक हो गया।


3. रैपिंग अपवाद

जाँच किए गए अपवाद सिद्धांत में अच्छे लगते थे, लेकिन व्यवहार में एक बड़ी हताशा के रूप में सामने आए।

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

इसका मतलब है कि आपको अपने सुपर लोकप्रिय विधि को कॉल करने वाली प्रत्येक विधि के खंड में चेक किए गए अपवाद कोthrows जोड़ना होगा । साथ ही throwsउन सभी विधियों के उपवाक्य में जो उन विधियों को कहते हैं। और उन विधियों को जो उन विधियों को कहते हैं।

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

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

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

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

जावा प्रोग्रामर्स ने चेक किए गए अपवादों को RuntimeException. दूसरे शब्दों में, सभी चेक किए गए अपवादों को पकड़ें और फिर अनियंत्रित अपवाद बनाएं (उदाहरण के लिए RuntimeException) और उन्हें इसके बजाय फेंक दें। ऐसा करने से कुछ ऐसा दिखता है:

try
{
   // Code where a checked exception might occur
}
catch(Exception exp)
{
   throw new RuntimeException(exp);
}

यह एक बहुत सुंदर समाधान नहीं है, लेकिन यहां कुछ भी आपराधिक नहीं है: अपवाद केवल एक RuntimeException.

आप चाहें तो इसे वहां से आसानी से प्राप्त कर सकते हैं। उदाहरण:

कोड टिप्पणी
try
{
   // Code where we wrap the checked exception
   // in a RuntimeException
}
catch(RuntimeException e)
{
   Throwable cause = e.getCause();
   if (cause instanceof Exception)
   {
      Exception exp = (Exception) cause;
      // Exception handling code goes here
   }
}







वस्तु के अंदर संग्रहीत अपवाद प्राप्त करें RuntimeException। चर causeशायद null

इसके प्रकार का निर्धारण करें और इसे एक चेक किए गए अपवाद प्रकार में परिवर्तित करें।


4. कई अपवादों को पकड़ना

प्रोग्रामर वास्तव में डुप्लिकेट कोड से नफरत करते हैं। यहां तक ​​कि उन्होंने इसी विकास सिद्धांत के साथ आए: डोंट रिपीट योरसेल्फ (DRY) । लेकिन अपवादों को संभालते समय, अक्सर ऐसे मौके आते हैं जब एक tryब्लॉक के बाद catchएक ही कोड वाले कई ब्लॉक होते हैं।

catchया एक ही कोड के साथ 3 ब्लॉक और catchअन्य समान कोड वाले 2 ब्लॉक हो सकते हैं । यह एक मानक स्थिति है जब आपकी परियोजना अपवादों को जिम्मेदारी से संभालती है।

catchसंस्करण 7 से शुरू होकर, जावा भाषा में एक ही ब्लॉक में कई प्रकार के अपवादों को निर्दिष्ट करने की क्षमता जोड़ी गई। ऐसा कुछ दिखता है:

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
   // Exception handling code
}

catchआप जितने चाहें उतने ब्लॉक रख सकते हैं । हालाँकि, एक एकल catchब्लॉक उन अपवादों को निर्दिष्ट नहीं कर सकता है जो एक दूसरे को विरासत में मिले हैं। दूसरे शब्दों में, आप पकड़ ( Exception| RuntimeExceptionई) नहीं लिख सकते, क्योंकि RuntimeExceptionवर्ग इनहेरिट करता है Exception



5. कस्टम अपवाद

आप हमेशा अपना अपवाद वर्ग बना सकते हैं। आप बस एक क्लास बनाते हैं जो RuntimeExceptionक्लास को इनहेरिट करती है। यह कुछ ऐसा दिखाई देगा:

class ClassName extends RuntimeException
{
}

जब आप OOP, इनहेरिटेंस, कंस्ट्रक्टर और मेथड ओवरराइडिंग सीखते हैं तो हम विवरणों पर चर्चा करेंगे।

हालाँकि, भले ही आपके पास केवल इस तरह का एक साधारण वर्ग हो (पूरी तरह से बिना कोड के), फिर भी आप इसके आधार पर अपवाद फेंक सकते हैं:

कोड टिप्पणी
class Solution
{
   public static void main(String[] args)
   {
      throw new MyException();
   }
}

class MyException extends RuntimeException
{
}




एक अनियंत्रित फेंको MyException

जावा मल्टीथ्रेडिंग खोज में , हम अपने स्वयं के कस्टम अपवादों के साथ काम करने के बारे में गहन जानकारी लेंगे।