जावा - अपवाद

एक अपवाद (या असाधारण घटना) एक समस्या है जो एक कार्यक्रम के निष्पादन के दौरान उत्पन्न होती है। जब एException तब होता है जब प्रोग्राम का सामान्य प्रवाह बाधित होता है और प्रोग्राम / एप्लिकेशन असामान्य रूप से समाप्त हो जाता है, जिसकी अनुशंसा नहीं की जाती है, इसलिए, इन अपवादों को नियंत्रित किया जाना है।

एक अपवाद कई अलग-अलग कारणों से हो सकता है। कुछ परिदृश्य निम्नलिखित हैं जहां अपवाद होता है।

  • उपयोगकर्ता ने एक अमान्य डेटा दर्ज किया है।

  • एक फ़ाइल जिसे खोलने की आवश्यकता है वह नहीं मिल सकती है।

  • संचार के बीच एक नेटवर्क कनेक्शन खो गया है या जेवीएम मेमोरी से बाहर चला गया है।

इनमें से कुछ अपवाद उपयोगकर्ता त्रुटि के कारण होते हैं, अन्य प्रोग्रामर त्रुटि से, और अन्य भौतिक संसाधनों द्वारा जो किसी तरह से विफल हो जाते हैं।

इनके आधार पर, हमारे पास अपवादों की तीन श्रेणियां हैं। आपको यह जानने की जरूरत है कि जावा में अपवाद हैंडलिंग कैसे काम करता है।

  • Checked exceptions- एक चेक किया गया अपवाद एक अपवाद है जिसे कंपाइलर-टाइम पर कंपाइलर द्वारा चेक (अधिसूचित) किया जाता है, इन्हें कंप्लीशन एक्सेप्शन भी कहा जाता है। इन अपवादों को अनदेखा नहीं किया जा सकता है, प्रोग्रामर को इन अपवादों का ध्यान रखना चाहिए।

उदाहरण के लिए, यदि आप उपयोग करते हैं FileReaderकिसी फ़ाइल से डेटा पढ़ने के लिए आपके प्रोग्राम में क्लास, यदि इसके निर्माता में निर्दिष्ट फ़ाइल मौजूद नहीं है, तो एक FileNotFoundException होती है, और कंपाइलर प्रोग्रामर को अपवाद को संभालने का संकेत देता है।

उदाहरण

import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {		
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

यदि आप उपरोक्त कार्यक्रम को संकलित करने का प्रयास करते हैं, तो आपको निम्नलिखित अपवाद मिलेंगे।

उत्पादन

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

Note - विधियों के बाद से read() तथा close() FileReader क्लास के IOException को फेंकता है, आप देख सकते हैं कि कंपाइलर IOException को हैंडल करने के लिए FileNotFoundException के साथ सूचित करता है।

  • Unchecked exceptions- अनियंत्रित अपवाद एक अपवाद है जो निष्पादन के समय होता है। इन्हें भी कहा जाता हैRuntime Exceptions। इनमें प्रोग्रामिंग बग शामिल हैं, जैसे तर्क त्रुटियां या एपीआई का अनुचित उपयोग। संकलन के समय रनटाइम अपवादों को अनदेखा किया जाता है।

उदाहरण के लिए, यदि आपने अपने कार्यक्रम में आकार 5 की एक सरणी घोषित की है, और सरणी के 6 वें तत्व को कॉल करने की कोशिश कर रहे हैं तो एक ArrayIndexOutOfBoundsExceptionexception होती है।

उदाहरण

public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

यदि आप उपरोक्त कार्यक्रम को संकलित और निष्पादित करते हैं, तो आपको निम्नलिखित अपवाद मिलेगा।

उत्पादन

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
  • Errors- ये अपवाद नहीं हैं, लेकिन उपयोगकर्ता या प्रोग्रामर के नियंत्रण से परे उत्पन्न होने वाली समस्याएं। आपके कोड में त्रुटियों को आमतौर पर नजरअंदाज कर दिया जाता है क्योंकि आप किसी त्रुटि के बारे में शायद ही कुछ कर सकते हैं। उदाहरण के लिए, यदि स्टैक ओवरफ्लो होता है, तो एक त्रुटि उत्पन्न होगी। संकलन के समय उन्हें भी नजरअंदाज किया जाता है।

अपवाद पदानुक्रम

सभी अपवाद वर्ग java.lang.Exception class के उपप्रकार हैं। अपवाद वर्ग थ्रेडेबल वर्ग का एक उपवर्ग है। अपवाद वर्ग के अलावा एक और उपवर्ग है, जिसे एरर कहा जाता है, जो थ्रोबेबल क्लास से लिया जाता है।

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

अपवाद कक्षा के दो मुख्य उपवर्ग हैं: IOException class और RuntimeException Class।

इसके बाद सबसे सामान्य जाँच और अनियंत्रित जावा के बिल्ट-इन अपवादों की एक सूची है ।

अपवाद तरीके

थ्रोबल श्रेणी में उपलब्ध महत्वपूर्ण विधियों की सूची निम्नलिखित है।

अनु क्रमांक। विधि और विवरण
1

public String getMessage()

अपवाद के बारे में एक विस्तृत संदेश देता है। यह संदेश थ्रेडेबल कंस्ट्रक्टर में आरंभिक है।

2

public Throwable getCause()

अपवाद का कारण देता है जैसा कि एक थ्रोबेबल ऑब्जेक्ट द्वारा दर्शाया गया है।

3

public String toString()

GetMessage () के परिणाम के साथ सम्‍मिलित वर्ग का नाम लौटाता है।

4

public void printStackTrace()

System.err, त्रुटि आउटपुट स्ट्रीम के स्टैक ट्रेस के साथ (।) के परिणाम प्रिंट करता है।

5

public StackTraceElement [] getStackTrace()

स्टैक ट्रेस पर प्रत्येक तत्व युक्त एक सरणी देता है। इंडेक्स 0 का तत्व कॉल स्टैक के शीर्ष का प्रतिनिधित्व करता है, और सरणी में अंतिम तत्व कॉल स्टैक के निचले भाग में विधि का प्रतिनिधित्व करता है।

6

public Throwable fillInStackTrace()

स्टैक ट्रेस में किसी भी पिछली जानकारी को जोड़कर, वर्तमान स्टैक ट्रेस के साथ इस थ्रेडेबल ऑब्जेक्ट के स्टैक ट्रेस को भरता है।

पकड़ने के अपवाद

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

वाक्य - विन्यास

try {
   // Protected code
} catch (ExceptionName e1) {
   // Catch block
}

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

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

उदाहरण

निम्नलिखित 2 तत्वों के साथ घोषित एक सरणी है। फिर कोड सरणी के 3 आरडी तत्व तक पहुंचने का प्रयास करता है जो एक अपवाद को फेंकता है।

// File Name : ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

यह निम्नलिखित परिणाम का उत्पादन करेगा -

उत्पादन

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

एकाधिक पकड़ ब्लॉक

एक कोशिश ब्लॉक का अनुसरण कई कैच ब्लॉक द्वारा किया जा सकता है। कई कैच ब्लॉक के लिए सिंटैक्स निम्न की तरह दिखता है -

वाक्य - विन्यास

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}

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

उदाहरण

यहां कोड सेगमेंट में यह दिखाया गया है कि कैसे कई कोशिशों / कैच स्टेटमेंट का उपयोग किया जाता है।

try {
   file = new FileInputStream(fileName);
   x = (byte) file.read();
} catch (IOException i) {
   i.printStackTrace();
   return -1;
} catch (FileNotFoundException f) // Not valid! {
   f.printStackTrace();
   return -1;
}

कई प्रकार के अपवादों को पकड़ना

जावा 7 के बाद से, आप सिंगल कैच ब्लॉक का उपयोग करके एक से अधिक अपवादों को संभाल सकते हैं, यह सुविधा कोड को सरल बनाती है। यहाँ है कि आप इसे कैसे करेंगे -

catch (IOException|FileNotFoundException ex) {
   logger.log(ex);
   throw ex;

थ्रो / थ्रो कीवर्ड

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

आप एक अपवाद फेंक सकते हैं, या तो एक नव तात्कालिकता या एक अपवाद जो आपने अभी पकड़ा है, का उपयोग करके throw कीवर्ड।

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

निम्नलिखित विधि घोषित करती है कि यह एक दूरस्थ अपवाद फेंकता है -

उदाहरण

import java.io.*;
public class className {

   public void deposit(double amount) throws RemoteException {
      // Method implementation
      throw new RemoteException();
   }
   // Remainder of class definition
}

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

उदाहरण

import java.io.*;
public class className {

   public void withdraw(double amount) throws RemoteException, 
      InsufficientFundsException {
      // Method implementation
   }
   // Remainder of class definition
}

अंत में ब्लॉक

अंत में ब्लॉक एक कोशिश ब्लॉक या कैच ब्लॉक का अनुसरण करता है। कोड का एक अंतिम ब्लॉक हमेशा निष्पादित होता है, चाहे एक अपवाद की घटना हो।

अंत में ब्लॉक का उपयोग करने से आप किसी भी क्लीन-टाइप स्टेटमेंट को चला सकते हैं, जिसे आप निष्पादित करना चाहते हैं, भले ही संरक्षित कोड में कुछ भी न हो।

अंत में ब्लॉक कैच ब्लॉक के अंत में दिखाई देता है और इसमें निम्नलिखित सिंटैक्स होता है -

वाक्य - विन्यास

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}finally {
   // The finally block always executes.
}

उदाहरण

public class ExcepTest {

   public static void main(String args[]) {
      int a[] = new int[2];
      try {
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }finally {
         a[0] = 6;
         System.out.println("First element value: " + a[0]);
         System.out.println("The finally statement is executed");
      }
   }
}

यह निम्नलिखित परिणाम का उत्पादन करेगा -

उत्पादन

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

निम्नलिखित नोट करें -

  • एक कोशिश बयान के बिना एक पकड़ खंड मौजूद नहीं हो सकता।

  • जब भी कोई ट्रायल / कैच ब्लॉक मौजूद होता है, तो क्लॉस का होना अनिवार्य नहीं है।

  • कोशिश ब्लॉक बिना क्लॉज या अंत में क्लॉज के मौजूद नहीं हो सकती।

  • कोई भी कोड कोशिश, पकड़, अंत में ब्लॉक के बीच मौजूद नहीं हो सकता है।

कोशिश-साथ-संसाधन

आम तौर पर, जब हम धाराओं, कनेक्शनों आदि जैसे किसी भी संसाधन का उपयोग करते हैं, तो हमें अंततः ब्लॉक का उपयोग करके उन्हें स्पष्ट रूप से बंद करना होगा। निम्नलिखित कार्यक्रम में, हम एक फ़ाइल का उपयोग करके डेटा पढ़ रहे हैंFileReader और हम इसे अंततः ब्लॉक का उपयोग करके बंद कर रहे हैं।

उदाहरण

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;		
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // reads the content to the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            fr.close();
         } catch (IOException ex) {		
            ex.printStackTrace();
         }
      }
   }
}

try-with-resources, के रूप में भी संदर्भित automatic resource management, जावा 7 में पेश किया गया एक नया अपवाद हैंडलिंग तंत्र है, जो कि स्वचालित रूप से ट्राई कैच ब्लॉक में उपयोग किए गए संसाधनों को बंद कर देता है।

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

वाक्य - विन्यास

try(FileReader fr = new FileReader("file path")) {
   // use the resource
   } catch () {
      // body of catch 
   }
}

निम्नलिखित प्रोग्राम है जो कोशिश-साथ-संसाधन विवरण का उपयोग करके फ़ाइल में डेटा पढ़ता है।

उदाहरण

import java.io.FileReader;
import java.io.IOException;

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // reads the contentto the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

कोशिश के साथ संसाधनों के बयान के साथ काम करते समय निम्नलिखित बिंदुओं को ध्यान में रखा जाना चाहिए।

  • कोशिश-संसाधनों के बयान के साथ एक वर्ग का उपयोग करने के लिए इसे लागू करना चाहिए AutoCloseable इंटरफ़ेस और close() इसका तरीका रनटाइम पर स्वचालित रूप से लागू हो जाता है।

  • आप कोशिश-के साथ संसाधनों के बयान में एक से अधिक वर्ग की घोषणा कर सकते हैं।

  • जब आप कोशिश-के-संसाधन संसाधनों की कोशिश ब्लॉक में कई वर्गों की घोषणा करते हैं तो ये कक्षाएं रिवर्स ऑर्डर में बंद हो जाती हैं।

  • कोष्ठक के भीतर संसाधनों की घोषणा को छोड़कर सब कुछ एक कोशिश ब्लॉक के सामान्य प्रयास / पकड़ने ब्लॉक के समान है।

  • प्रयास में घोषित संसाधन, कोशिश-ब्लॉक के शुरू होने से ठीक पहले हो जाता है।

  • ट्रायल ब्लॉक में घोषित संसाधन को अंतिम रूप से घोषित किया जाता है।

उपयोगकर्ता-परिभाषित अपवाद

आप अपने स्वयं के अपवाद जावा में बना सकते हैं। अपने स्वयं के अपवाद वर्गों को लिखते समय निम्नलिखित बिंदुओं को ध्यान में रखें -

  • सभी अपवादों को थ्रोएबल का बच्चा होना चाहिए।

  • यदि आप एक जाँच अपवाद लिखना चाहते हैं जो स्वचालित रूप से हैंडल या डिक्लेयर नियम द्वारा लागू किया जाता है, तो आपको अपवाद वर्ग को विस्तारित करने की आवश्यकता है।

  • यदि आप रनटाइम अपवाद लिखना चाहते हैं, तो आपको RuntimeException class को विस्तारित करने की आवश्यकता है।

हम अपने स्वयं के अपवाद वर्ग को नीचे के रूप में परिभाषित कर सकते हैं -

class MyException extends Exception {
}

आपको बस पूर्वनिर्धारित का विस्तार करने की आवश्यकता है Exceptionअपनी खुद की अपवाद बनाने के लिए कक्षा। इन्हें अपवाद माना जाता है। निम्नलिखितInsufficientFundsExceptionवर्ग एक उपयोगकर्ता-परिभाषित अपवाद है जो अपवाद वर्ग का विस्तार करता है, यह एक जाँच अपवाद है। एक अपवाद वर्ग किसी भी अन्य वर्ग की तरह है, जिसमें उपयोगी क्षेत्र और विधियां हैं।

उदाहरण

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception {
   private double amount;
   
   public InsufficientFundsException(double amount) {
      this.amount = amount;
   }
   
   public double getAmount() {
      return amount;
   }
}

हमारे उपयोगकर्ता-परिभाषित अपवाद का उपयोग करते हुए प्रदर्शित करने के लिए, निम्नलिखित CheckingAccount वर्ग में एक InsufficFundsException फेंकता है जो एक वापसी () विधि है।

// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount {
   private double balance;
   private int number;
   
   public CheckingAccount(int number) {
      this.number = number;
   }
   
   public void deposit(double amount) {
      balance += amount;
   }
   
   public void withdraw(double amount) throws InsufficientFundsException {
      if(amount <= balance) {
         balance -= amount;
      }else {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   
   public double getBalance() {
      return balance;
   }
   
   public int getNumber() {
      return number;
   }
}

निम्नलिखित BankDemo कार्यक्रम जमा () और आहरण () CheckingAccount के तरीकों को प्रदर्शित करता है।

// File Name BankDemo.java
public class BankDemo {

   public static void main(String [] args) {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      
      try {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      } catch (InsufficientFundsException e) {
         System.out.println("Sorry, but you are short $" + e.getAmount());
         e.printStackTrace();
      }
   }
}

उपरोक्त सभी तीन फ़ाइलों को संकलित करें और BankDemo चलाएं। यह निम्नलिखित परिणाम का उत्पादन करेगा -

उत्पादन

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
         at CheckingAccount.withdraw(CheckingAccount.java:25)
         at BankDemo.main(BankDemo.java:13)

आम अपवाद

जावा में, अपवादों और त्रुटियों के दो कैटरगरीज को परिभाषित करना संभव है।

  • JVM Exceptions- ये अपवाद / त्रुटियां हैं जो विशेष रूप से या तार्किक रूप से JVM द्वारा फेंकी जाती हैं। उदाहरण: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException।

  • Programmatic Exceptions- इन अपवादों को एप्लिकेशन या एपीआई प्रोग्रामर द्वारा स्पष्ट रूप से फेंक दिया जाता है। उदाहरण: IllegalArgumentException, IllegalStateException।