CodeGym /Java Blog /यादृच्छिक /अपवाद: पकडणे आणि हाताळणे
John Squirrels
पातळी 41
San Francisco

अपवाद: पकडणे आणि हाताळणे

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
हाय! मला त्याचा उल्लेख करणे आवडत नाही, परंतु प्रोग्रामरच्या कार्याचा एक मोठा भाग त्रुटींशी संबंधित आहे. बर्याचदा, त्याच्या किंवा तिच्या स्वत: च्या. असे दिसून आले की असे कोणतेही लोक नाहीत जे चुका करत नाहीत. आणि असे कोणतेही कार्यक्रम नाहीत. अपवाद: पकडणे आणि हाताळणे - १ अर्थात, त्रुटी हाताळताना, मुख्य गोष्ट म्हणजे त्याचे कारण समजून घेणे. आणि बर्‍याच गोष्टींमुळे प्रोग्राममध्ये बग येऊ शकतात. काही क्षणी, जावाच्या निर्मात्यांनी स्वतःला विचारले की बहुधा प्रोग्रामिंग त्रुटींचे काय करावे? त्यांना पूर्णपणे टाळणे वास्तववादी नाही, प्रोग्रामर अशी सामग्री लिहिण्यास सक्षम आहेत ज्याची आपण कल्पना देखील करू शकत नाही. :) म्हणून, आपण भाषेला त्रुटींसह कार्य करण्याची यंत्रणा दिली पाहिजे. दुसऱ्या शब्दांत, तुमच्या प्रोग्राममध्ये त्रुटी असल्यास, पुढे काय करावे यासाठी तुम्हाला काही प्रकारच्या स्क्रिप्टची आवश्यकता आहे. जेव्हा एखादी त्रुटी येते तेव्हा प्रोग्रामने नेमके काय करावे? आज आपण या यंत्रणेशी परिचित होऊ. याला " Java मधील अपवाद " म्हणतात.

अपवाद काय?

अपवाद म्हणजे अपवादात्मक, अनियोजित परिस्थिती जी प्रोग्राम चालू असताना उद्भवते. अनेक अपवाद आहेत. उदाहरणार्थ, तुम्ही कोड लिहिला आहे जो फाईलमधील मजकूर वाचतो आणि पहिली ओळ प्रदर्शित करतो.

public class Main {

   public static void main(String[] args) throws IOException {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   }
}
पण अशी फाईल नसेल तर काय! कार्यक्रम अपवाद निर्माण करेल: FileNotFoundException. आउटपुट: "मुख्य" थ्रेडमधील अपवाद java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (सिस्टम निर्दिष्ट मार्ग शोधू शकत नाही) Java मध्ये, प्रत्येक अपवाद वेगळ्या वर्गाद्वारे दर्शविला जातो. हे सर्व अपवाद वर्ग सामान्य "पूर्वज" - Throwableपालक वर्गापासून प्राप्त झाले आहेत. अपवाद वर्गाचे नाव सामान्यत: अपवाद का आला ते प्रतिबिंबित करते:
  • FileNotFoundException(फाइल सापडली नाही)

  • ArithmeticException(गणितीय ऑपरेशन करताना अपवाद आला)

  • ArrayIndexOutOfBoundsException(इंडेक्स अॅरेच्या सीमांच्या पलीकडे आहे). उदाहरणार्थ, फक्त 10 घटक असलेल्या अॅरेचे स्थान 23 प्रदर्शित करण्याचा प्रयत्न केल्यास हा अपवाद येतो.
एकूण, जावामध्ये असे जवळपास ४०० वर्ग आहेत! इतके का? प्रोग्रामरना काम करण्यासाठी त्यांना अधिक सोयीस्कर बनवण्यासाठी. याची कल्पना करा: तुम्ही एक प्रोग्राम लिहिता आणि तो चालवत असताना तो अपवाद व्युत्पन्न करतो जो यासारखा दिसतो:

Exception in thread "main"
उह्ह्ह. :/ याचा फारसा उपयोग होत नाही. त्रुटी म्हणजे काय किंवा ती कुठून आली हे स्पष्ट नाही. येथे कोणतीही उपयुक्त माहिती नाही. परंतु Java मधील अपवाद वर्गांची मोठी विविधता प्रोग्रामरला सर्वात महत्त्वाची गोष्ट देते: त्रुटीचा प्रकार आणि त्याचे संभाव्य कारण (वर्गाच्या नावात एम्बेड केलेले). ती पाहण्यासारखी दुसरी गोष्ट आहे

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (The system cannot find the specified path)
समस्या काय असू शकते आणि समस्येचे निराकरण करण्यासाठी कुठे खोदणे सुरू करावे हे लगेच स्पष्ट होते! अपवाद, कोणत्याही वर्गाच्या उदाहरणांप्रमाणे, वस्तू आहेत.

अपवाद पकडणे आणि हाताळणे

Java मध्ये अपवादांसह कार्य करण्यासाठी कोडचे विशेष ब्लॉक्स आहेत: try, catchआणि finally. अपवाद: पकडणे आणि हाताळणे - 2 कोड जेथे प्रोग्रामरला अपवाद असू शकतो असे वाटते तो ब्लॉकमध्ये ठेवला जातो try. याचा अर्थ इथे अपवाद होईलच असे नाही. याचा अर्थ असा आहे की ते येथे होऊ शकते आणि प्रोग्रामरला या शक्यतेची जाणीव आहे. तुम्हाला अपेक्षित त्रुटीचा प्रकार ब्लॉकमध्ये ठेवला आहे catch. यामध्ये अपवाद आढळल्यास अंमलात आणले जावे असे सर्व कोड देखील समाविष्ट आहेत. येथे एक उदाहरण आहे:

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {

       System.out.println("Error! File not found!");
   }
}
आउटपुट: त्रुटी! फाइल सापडली नाही! आम्ही आमचा कोड दोन ब्लॉक्समध्ये ठेवतो. पहिल्या ब्लॉकमध्ये, "फाइल सापडली नाही" त्रुटी उद्भवू शकते असा आमचा अंदाज आहे. हा tryब्लॉक आहे. दुसऱ्यामध्ये, एखादी त्रुटी आढळल्यास काय करावे हे आम्ही प्रोग्रामला सांगतो. आणि विशिष्ट त्रुटी प्रकार: FileNotFoundException. जर आपण ब्लॉकच्या कंसात वेगळा अपवाद वर्ग ठेवला catchतर तो FileNotFoundExceptionपकडला जाणार नाही.

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (ArithmeticException e) {

       System.out.println("Error! File not found!");
   }
}
आउटपुट: "मुख्य" थ्रेडमधील अपवाद java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (सिस्टीम निर्दिष्ट मार्ग शोधू शकत नाही) ब्लॉकमधील कोड catchचालला नाही, कारण आम्ही "कॉन्फिगर" केले आहे. हा ब्लॉक पकडण्यासाठी ArithmeticException, आणि ब्लॉकमधील कोड tryभिन्न प्रकार फेकले: FileNotFoundException. आम्ही हाताळण्यासाठी कोणताही कोड लिहिला नाही FileNotFoundException, म्हणून प्रोग्राम साठी डीफॉल्ट माहिती प्रदर्शित करतो FileNotFoundException. येथे तुम्हाला तीन गोष्टींकडे लक्ष देणे आवश्यक आहे. पहीला क्रमांक. ब्लॉकमधील काही ओळीवर अपवाद आला की try, खालील कोड कार्यान्वित केला जाणार नाही. प्रोग्रामची अंमलबजावणी त्वरित ब्लॉकवर "उडी मारते" catch. उदाहरणार्थ:

public static void main(String[] args) {
   try {
       System.out.println("Divide by zero");
       System.out.println(366/0);// This line of code will throw an exception

       System.out.println("This");
       System.out.println("code");
       System.out.println("will not");
       System.out.println("be");
       System.out.println("executed!");

   } catch (ArithmeticException e) {

       System.out.println("The program jumped to the catch block!");
       System.out.println("Error! You can't divide by zero!");
   }
}
आउटपुट: शून्याने विभाजित करा प्रोग्राम कॅच ब्लॉकवर गेला! चूक! तुम्ही शून्याने भागू शकत नाही! ब्लॉकच्या दुसर्‍या ओळीवर try, आम्ही 0 ने विभाजित करण्याचा प्रयत्न करतो, परिणामी ArithmeticException. परिणामी, ब्लॉकच्या 3-9 ओळी tryकार्यान्वित केल्या जाणार नाहीत. आम्ही म्हटल्याप्रमाणे, प्रोग्राम त्वरित catchब्लॉक कार्यान्वित करण्यास सुरवात करतो. क्रमांक दोन. अनेक ब्लॉक्स असू शकतात catch. जर ब्लॉकमधील कोड tryएक नाही तर अनेक प्रकारचे अपवाद टाकत असेल, तर तुम्ही catchत्या प्रत्येकासाठी ब्लॉक लिहू शकता.

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       System.out.println(366/0);
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
      
       System.out.println("Error! File not found!");
      
   } catch (ArithmeticException e) {

       System.out.println("Error! Division by 0!");
      
   }
}
या उदाहरणात, आम्ही दोन catchब्लॉक्स लिहिले आहेत. FileNotFoundExceptionब्लॉकमध्ये आढळल्यास , tryपहिला catchब्लॉक कार्यान्वित केला जाईल. आढळल्यास ArithmeticException, दुसरा ब्लॉक कार्यान्वित केला जाईल. catchतुम्हाला हवे असल्यास तुम्ही 50 ब्लॉक्स लिहू शकता . अर्थात, 50 भिन्न प्रकारचे अपवाद टाकू शकेल असा कोड न लिहिणे चांगले. :) तिसरा. तुमचा कोड कोणता अपवाद टाकू शकतो हे तुम्हाला कसे कळेल? बरं, आपण त्यापैकी काहींचा अंदाज लावू शकता, परंतु सर्वकाही आपल्या डोक्यात ठेवणे आपल्यासाठी अशक्य आहे. त्यामुळे जावा कंपाइलरला सर्वात सामान्य अपवाद आणि ते कोणत्या परिस्थितीत येऊ शकतात हे माहीत आहे. उदाहरणार्थ, कंपाइलरला माहीत असलेला कोड तुम्ही दोन प्रकारचे अपवाद टाकू शकतात असे लिहिल्यास, तुमचा कोड जोपर्यंत तुम्ही हाताळत नाही तोपर्यंत तो संकलित होणार नाही. याची उदाहरणे आपण खाली पाहू. आता अपवाद हाताळण्याबद्दल काही शब्द. अपवाद हाताळण्याचे 2 मार्ग आहेत. आम्‍ही याआधीच पहिला सामना केला आहे: पद्धत ब्लॉकमध्‍येच अपवाद हाताळू शकते catch(). दुसरा पर्याय आहे: पद्धत कॉल स्टॅकवर अपवाद पुन्हा फेकून देऊ शकते. याचा अर्थ काय? उदाहरणार्थ, आमच्याकडे समान पद्धतीचा वर्ग आहे printFirstString(), जो फाइल वाचतो आणि त्याची पहिली ओळ प्रदर्शित करतो:

public static void printFirstString(String filePath) {

   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
सध्या, आमचा कोड संकलित करत नाही, कारण त्यात न हाताळलेले अपवाद आहेत. ओळ 1 मध्ये, तुम्ही फाइलचा मार्ग निर्दिष्ट करता. कंपायलरला माहित आहे की असा कोड सहजपणे तयार करू शकतो FileNotFoundException. ओळ 3 मध्ये, तुम्ही फाइलमधील मजकूर वाचता. या प्रक्रियेचा परिणाम सहजपणे IOException(इनपुट/आउटपुट त्रुटी) होऊ शकतो. आता कंपाइलर तुम्हाला म्हणतो, "मित्रा, मी हा कोड मंजूर करणार नाही आणि जोपर्यंत तुम्ही मला सांगता की यापैकी एखादा अपवाद आला तर मी काय करावे हे सांगेपर्यंत मी तो संकलित करणार नाही. आणि ते तुम्ही लिहिलेल्या कोडच्या आधारे नक्कीच घडू शकतात. !" त्याभोवती जाण्याचा कोणताही मार्ग नाही: आपल्याला दोन्ही हाताळण्याची आवश्यकता आहे! आम्हाला पहिल्या अपवाद हाताळणी पद्धतीबद्दल आधीच माहिती आहे: आम्हाला आमचा कोड ब्लॉकमध्ये ठेवण्याची tryआणि दोन catchब्लॉक जोडण्याची आवश्यकता आहे:

public static void printFirstString(String filePath) {

   try {
       BufferedReader reader = new BufferedReader(new FileReader(filePath));
       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error, file not found!");
       e.printStackTrace();
   } catch (IOException e) {
       System.out.println("File input/output error!");
       e.printStackTrace();
   }
}
पण हा एकमेव पर्याय नाही. पद्धतीमध्ये त्रुटी-हँडलिंग कोड लिहिण्याऐवजी आम्ही अपवाद फक्त वर टाकू शकतो. throwsहे मेथड डिक्लेरेशनमधील कीवर्ड वापरून केले जाते :

public static void printFirstString(String filePath) throws FileNotFoundException, IOException {
   BufferedReader reader = new BufferedReader(new FileReader(filePath));
   String firstString = reader.readLine();
   System.out.println(firstString);
}
कीवर्ड नंतर throws, आम्ही पद्धत टाकू शकणार्‍या सर्व प्रकारच्या अपवादांची स्वल्पविरामाने विभक्त केलेली सूची सूचित करतो. का? printFirstString()आता, जर एखाद्याला प्रोग्राममधील पद्धत कॉल करायची असेल , तर त्याला किंवा तिला (तुम्ही नाही) अपवाद हाताळणी लागू करावी लागेल. उदाहरणार्थ, समजा की प्रोग्राममध्ये इतरत्र तुमच्या एका सहकाऱ्याने एक पद्धत लिहिली आहे जी तुमच्या printFirstString()पद्धतीला कॉल करते:

public static void yourColleagueMethod() {

   // Your colleague's method does something

   //...and then calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Henry\\Desktop\\testFile.txt");
}
आम्हाला एक त्रुटी आली! हा कोड संकलित होणार नाही! आम्ही पद्धतीमध्ये अपवाद-हँडलिंग कोड लिहिला नाही printFirstString(). परिणामी, हे काम आता पद्धत वापरणाऱ्यांच्या खांद्यावर येते. दुसऱ्या शब्दांत, methodWrittenByYourColleague()पद्धतीमध्ये आता समान 2 पर्याय आहेत: try-catchदोन्ही अपवाद हाताळण्यासाठी एकतर ब्लॉक वापरणे आवश्यक आहे किंवा ते पुन्हा फेकणे आवश्यक आहे.

public static void yourColleagueMethod() throws FileNotFoundException, IOException {
   // The method does something

   //...and then calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Henry\\Desktop\\testFile.txt");
}
दुस-या बाबतीत, कॉल स्टॅकमधील पुढील पद्धत—एक कॉल करत आहे methodWrittenByYourColleague()—त्याला अपवाद हाताळावे लागतील. म्हणूनच आम्ही याला "अपवाद वर फेकणे किंवा पास करणे" म्हणतो. तुम्ही कीवर्ड वापरून अपवाद वरच्या दिशेने टाकल्यास throws, तुमचा कोड संकलित होईल. या टप्प्यावर, कंपाइलर म्हणत असल्याचे दिसते, "ठीक आहे, ठीक आहे. तुमच्या कोडमध्ये संभाव्य अपवादांचा एक समूह आहे, परंतु मी ते संकलित करेन. परंतु आम्ही या संभाषणाकडे परत येऊ!" आणि जेव्हा तुम्ही कोणत्याही पद्धतीला कॉल करता ज्यामध्ये न हाताळलेले अपवाद असतात, तेव्हा कंपायलर त्याचे वचन पूर्ण करतो आणि तुम्हाला त्यांची पुन्हा आठवण करून देतो. शेवटी, आम्ही ब्लॉकबद्दल बोलू finally(श्लेषाबद्दल क्षमस्व). हा अपवाद हाताळणीचा शेवटचा भाग आहे try-catch-finallyट्रायमविरेट..

public static void main(String[] args) throws IOException {
   try {
       BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       System.out.println("Error! File not found!");
       e.printStackTrace();
   } finally {
       System.out.println ("And here's the finally block!");
   }
}
या उदाहरणात, ब्लॉकमधील कोड finallyदोन्ही प्रकरणांमध्ये कार्यान्वित केला जाईल. ब्लॉकमधील कोड tryकोणताही अपवाद न टाकता पूर्ण रन केल्यास, finallyब्लॉक शेवटी रन होईल. ब्लॉकमधील कोड tryअपवादाने व्यत्यय आणल्यास आणि प्रोग्राम ब्लॉकवर उडी मारल्यास catch, finallyब्लॉक अजूनही ब्लॉकमधील कोडच्या नंतर चालेल catch. हे का आवश्यक आहे? त्याचा मुख्य उद्देश अनिवार्य कोड अंमलात आणणे हा आहे: कोड जो परिस्थितीची पर्वा न करता केला जाणे आवश्यक आहे. उदाहरणार्थ, प्रोग्रामद्वारे वापरलेली काही संसाधने ते सहसा मुक्त करते. आमच्या कोडमध्ये, आम्ही फाईलमधील माहिती वाचण्यासाठी एक प्रवाह उघडतो आणि ती ऑब्जेक्टवर पास करतो BufferedReader. आम्ही आमचे वाचक बंद केले पाहिजे आणि संसाधने सोडली पाहिजेत. हे काहीही असले तरीही केले जाणे आवश्यक आहे—जेव्हा प्रोग्राम पाहिजे तसे कार्य करतो आणि जेव्हा तो अपवाद करतो. finallyहे करण्यासाठी ब्लॉक एक अतिशय सोयीस्कर जागा आहे :

public static void main(String[] args) throws IOException {

   BufferedReader reader = null;
   try {
       reader = new BufferedReader(new FileReader("C:\\Users\\Username\\Desktop\\test.txt"));

       String firstString = reader.readLine();
       System.out.println(firstString);
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   } finally {
       System.out.println ("And here's the finally block!");
       if (reader != null) {
           reader.close();
       }
   }
}
आता आम्हाला खात्री आहे की प्रोग्राम चालू असताना काय होते याची पर्वा न करता आम्ही संसाधनांची काळजी घेऊ. :) अपवादांबद्दल तुम्हाला इतकेच माहित असणे आवश्यक नाही. प्रोग्रामिंगमध्ये त्रुटी हाताळणे हा एक अतिशय महत्त्वाचा विषय आहे. बरेच लेख त्याला समर्पित आहेत. पुढील धड्यात, कोणत्या प्रकारचे अपवाद आहेत आणि तुमचे स्वतःचे अपवाद कसे तयार करायचे ते आम्ही शोधू. :) मग भेटूया आपण!
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION