JavaRush /جاوا بلاگ /Random-SD /جاوا ۾ استثنا: پڪڙڻ ۽ هٿ ڪرڻ

جاوا ۾ استثنا: پڪڙڻ ۽ هٿ ڪرڻ

گروپ ۾ شايع ٿيل
سلام! مون کي ان کي ٽوڙڻ کان نفرت آهي، پر هڪ پروگرامر جي نوڪري جو هڪ وڏو حصو غلطين سان معاملو آهي. ۽ اڪثر ڪري - انھن سان گڏ. بس ائين ٿئي ٿو ته اهڙا ماڻهو نه آهن جيڪي غلطيون نه ڪن. ۽ نه ته اهڙا پروگرام آهن. يقينا، بنيادي شيء جڏهن غلطي تي ڪم ڪري رهيو آهي ان جي سبب کي سمجهڻ آهي. ۽ پروگرام ۾ اهڙن سببن جو هڪ پورو گروپ ٿي سگهي ٿو. هڪ نقطي تي، جاوا جي تخليق ڪندڙن کي هڪ سوال سان منهن ڏيڻو پيو: پروگرامن ۾ انهن تمام امڪاني غلطين سان ڇا ڪجي؟ انهن کان پاسو ڪرڻ بلڪل غير حقيقي آهي. پروگرامر ڪجهه لکي سگھن ٿا جنهن جو تصور ڪرڻ به ناممڪن آهي :) هن جو مطلب اهو آهي ته اهو ضروري آهي ته ٻولي ۾ غلطين سان معاملو ڪرڻ لاء هڪ ميکانيزم ٺاهيو وڃي. ٻين لفظن ۾، جيڪڏهن پروگرام ۾ ڪجهه غلطي ٿي وئي آهي، هڪ اسڪرپٽ وڌيڪ ڪم لاء گهربل آهي. پروگرام کي ڇا ڪرڻ گهرجي جڏهن هڪ غلطي ٿئي ٿي؟ اڄ اسان هن ميکانيزم سان واقف ٿي ويندي. ۽ ان کي سڏيو ويندو آهي "استثنات " .

جاوا ۾ هڪ استثنا ڇا آهي

هڪ استثنا ڪجهه غير معمولي، غير منصوبابندي واري صورتحال آهي جيڪا پروگرام جي آپريشن دوران واقع ٿي. جاوا ۾ استثنا جا ڪيترائي مثال ٿي سگھن ٿا. مثال طور، توهان ڪوڊ لکيو آهي جيڪو فائل مان ٽيڪسٽ پڙهي ٿو ۽ ڪنسول ڏانهن پهرين لائن ڏيکاري ٿو.
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. نتيجو:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
هر استثنا جاوا ۾ هڪ الڳ طبقي جي نمائندگي ڪئي وئي آهي. سڀ استثنائي طبقا هڪ عام ”ابن ڏاڏن“ مان ايندا آهن - والدين طبقو Throwable. استثنا طبقي جو نالو عام طور تي مختصر طور تي ان جي واقعن جو سبب ظاهر ڪري ٿو:
  • FileNotFoundException(فائل نه ملي)
  • ArithmeticException(استثنائي جڏهن رياضي جي عمل کي انجام ڏيڻ)
  • ArrayIndexOutOfBoundsException(سري سيل جو تعداد ان جي ڊيگهه کان ٻاهر بيان ڪيو ويو آهي). مثال طور، جيڪڏھن توھان ڪوشش ڪندا آھيو ته سيل جي صف کي ٻاھر ڪڍو [23] کنسول ڏانھن لمبائي 10 جي صف جي صف لاءِ.
جاوا ۾ لڳ ڀڳ 400 اهڙا ڪلاس آهن! ايترا گهڻا ڇو؟ خاص طور تي ان کي وڌيڪ آسان بڻائڻ لاءِ پروگرامر انهن سان ڪم ڪرڻ لاءِ. تصور ڪريو: توھان ھڪڙو پروگرام لکيو آھي، ۽ جڏھن اھو ھلندو آھي، اھو ھڪڙو استثنا اڇلائي ٿو جيڪو ھن وانگر ڏسڻ ۾ اچي ٿو:
Exception in thread "main"
Uh-uh :/ ڪجھ به واضح ناهي. اها ڪهڙي قسم جي غلطي آهي ۽ اها ڪٿان آئي آهي واضح ناهي. ڪابه مفيد معلومات نه آهي. پر اهڙي قسم جي طبقن جي مهرباني، پروگرامر پاڻ لاء بنيادي شيء حاصل ڪري ٿو - غلطي جو قسم ۽ ان جو امڪاني سبب، جيڪو ڪلاس جي نالي تي مشتمل آهي. آخرڪار، اهو ڪنسول ۾ ڏسڻ لاء هڪ مڪمل طور تي مختلف شيء آهي:
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
اهو فوري طور تي واضح ٿي وڃي ٿو ته مسئلو ڇا ٿي سگهي ٿو ۽ مسئلو حل ڪرڻ لاءِ ”ڪهڙي طرف کڏڻ“! استثنا، طبقن جي ڪنهن به مثال وانگر، شيون آهن.

پڪڙڻ ۽ سنڀالڻ استثنا

جاوا ۾ استثنا سان ڪم ڪرڻ لاء، خاص ڪوڊ بلاڪ آهن: 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هڪ ٻيو استثنا ڪلاس پاس ڪريون ٿا بلاڪ بریکٹ ۾، اهو پڪڙي نه سگهندو.
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!");
   }
}
نتيجو:

Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (Системе не удается найти указанный путь)
بلاڪ ۾ ڪوڊ catchڪم نه ڪيو ڇاڪاڻ ته اسان هن بلاڪ کي "ترتيب" ۾ مداخلت ڪرڻ لاء ArithmeticException، ۽ بلاڪ ۾ ڪوڊ tryهڪ ٻيو قسم ڪڍي ڇڏيو - FileNotFoundException. اسان لاءِ اسڪرپٽ نه لکيو آهي FileNotFoundException، تنهنڪري پروگرام ڪنسول ۾ ڏيکاريل معلومات جيڪا ڊفالٽ لاءِ ڏيکاري ٿي FileNotFoundException. هتي توهان کي 3 شين تي ڌيان ڏيڻ جي ضرورت آهي. پهريون. جيئن ئي ڪو استثنا ٿئي ٿو ڪوڊ جي ڪنهن به قطار ۾ هڪ ڪوشش بلاڪ ۾، ان کان پوء ڪوڊ وڌيڪ عمل نه ڪيو ويندو. پروگرام جي عمل کي فوري طور تي بلاڪ ڏانهن "جمپ" ٿيندو catch. مثال طور:
public static void main(String[] args) {
   try {
       System.out.println("Divide a number 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("Not");
       System.out.println("will");
       System.out.println("done!");

   } catch (ArithmeticException e) {

       System.out.println("The program jumped to the catch block!");
       System.out.println("Error! You can't divide by zero!");
   }
}
نتيجو:

Делим число на ноль 
Программа перепрыгнула в блок catch! 
Ошибка! Нельзя делить на ноль! 
tryٻئين لڪير ۾ بلاڪ ۾ ، اسان هڪ نمبر کي 0 سان ورهائڻ جي ڪوشش ڪئي، جنهن جي نتيجي ۾ هڪ استثنا آهي ArithmeticException. ان کان پوء، بلاڪ جون لائينون 6-10 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. جيڪڏهن، بلاڪ ۾ tryٿئي ٿي FileNotFoundException، پهرين بلاڪ تي عمل ڪيو ويندو catch. جيڪڏهن ائين ٿئي ٿو ArithmeticException، ته ٻيو عمل ڪيو ويندو. توهان گهٽ ۾ گهٽ 50 بلاڪ لکي سگهو ٿا catch، پر، يقينا، اهو بهتر ناهي ته ڪوڊ نه لکو جيڪو 50 مختلف قسمن جي غلطين کي اڇلائي سگهي ٿو :) ٽيون. توهان کي ڪيئن خبر آهي ته توهان جو ڪوڊ اڇلائي سگھي ٿو ڪهڙا استثنا؟ خير، توهان ڪري سگهو ٿا، يقينا، ڪجهه بابت اندازو لڳايو، پر اهو ناممڪن آهي ته هر شي کي توهان جي سر ۾ رکڻ لاء. تنهن ڪري، جاوا گڏ ڪرڻ وارو سڀ کان عام استثناء جي باري ۾ ڄاڻي ٿو ۽ ڄاڻي ٿو ته اهي ڪهڙي حالتن ۾ ٿي سگهن ٿيون. مثال طور، جيڪڏهن توهان ڪوڊ لکيو آهي ۽ مرتب ڪندڙ ڄاڻي ٿو ته ان جي آپريشن دوران 2 قسم جا استثنا ٿي سگهن ٿا، توهان جو ڪوڊ مرتب نه ٿيندو جيستائين توهان انهن کي سنڀاليندؤ. ان جا مثال هيٺ ڏجن ٿا. هاڻي استثنا سنڀالڻ جي حوالي سان. انھن کي پروسيس ڪرڻ لاء 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هن عمل ۾ ، ان پٽ-آئوٽ پُٽ (Input-Output) دوران هڪ غلطي آساني سان ٿي سگهي ٿي . ھاڻي مرتب ڪندڙ توھان کي ٻڌائي رھيو آھي، ”يار، مان ھن ڪوڊ کي منظور نه ڪندس يا ان کي مرتب نه ڪندس جيستائين توھان مون کي نه ٻڌايو ته جيڪڏھن انھن مان ھڪڙو استثنا ٿئي ته مون کي ڇا ڪرڻ گھرجي. ۽ اهي ضرور ٿي سگهن ٿا توهان جي لکيل ڪوڊ جي بنياد تي! . اتي وڃڻ لاء ڪٿي به ناهي، توهان ٻنهي کي پروسيس ڪرڻ جي ضرورت آهي! پهرين پروسيسنگ آپشن اسان کي اڳ ۾ ئي واقف آهي: اسان کي اسان جي ڪوڊ کي بلاڪ ۾ رکڻو پوندو 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("Error while inputting/outputting data from file!");
       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 at one moment calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Eugene\\Desktop\\testFile.txt");
}
غلطي، ڪوڊ مرتب نٿو ڪري! اسان طريقي ۾ printFirstString()غلطي کي سنڀالڻ واري اسڪرپٽ نه لکيو آهي . تنهن ڪري، ڪم انهن جي ڪلهن تي پوي ٿو جيڪي هن طريقي کي استعمال ڪندا. اهو آهي، طريقو yourColleagueMethod()هاڻي ساڳيون 2 اختيارن کي منهن ڏئي ٿو: ان کي يا ته انهن ٻنهي استثنان تي عمل ڪرڻ گهرجي جيڪي ان کي استعمال ڪندي "fly" ويا try-catch، يا انهن کي اڳتي وڌايو.
public static void yourColleagueMethod() throws FileNotFoundException, IOException {
   //...the method does something

   //...and at one moment calls your printFirstString() method with the file it needs
   printFirstString("C:\\Users\\Eugene\\Desktop\\testFile.txt");
}
ٻئين صورت ۾، پروسيسنگ اسٽيڪ تي ايندڙ طريقي جي ڪلهن تي ٿيندي - جيڪو سڏيندو yourColleagueMethod(). اهو ئي سبب آهي ته اهڙي ميکانيزم کي سڏيو ويندو آهي "هڪ استثنا کي مٿي اڇلائڻ"، يا "مٿي ڏانهن گذري". جڏهن توهان استعمال ڪندي استثنا اڇلايو 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 is the finally block!");
   }
}
هن مثال ۾، بلاڪ اندر ڪوڊ finallyٻنهي صورتن ۾ عمل ڪيو ويو آهي. جيڪڏهن بلاڪ ۾ ڪوڊ tryمڪمل طور تي عمل ڪيو ويو آهي ۽ هڪ استثنا نه اڇلائي، بلاڪ آخر ۾ فائر ڪندو finally. جيڪڏهن ڪوڊ اندر tryمداخلت ڪئي وئي آهي ۽ پروگرام بلاڪ ڏانهن ڇڪيندو آهي catch، ڪوڊ جي اندر عمل ٿيڻ کان پوء catch، بلاڪ اڃا تائين چونڊيو ويندو finally. ان جي ضرورت ڇو آهي؟ ان جو بنيادي مقصد ڪوڊ جي گهربل حصي تي عمل ڪرڻ آهي؛ اھو حصو جيڪو مڪمل ٿيڻ گھرجي حالتن کان سواءِ. مثال طور، اهو اڪثر ڪري پروگرام پاران استعمال ڪيل ڪجهه وسيلن کي آزاد ڪري ٿو. اسان جي ڪوڊ ۾، اسان فائل مان معلومات پڙهڻ لاء هڪ وهڪرو کوليو ۽ ان کي منتقل ڪيو BufferedReader. اسان کي readerبند ڪرڻ جي ضرورت آهي ۽ وسيلن کي آزاد ڪيو وڃي. اهو ڪنهن به صورت ۾ ٿيڻ گهرجي: اهو مسئلو ناهي ته ڇا پروگرام توقع جي مطابق ڪم ڪري ٿو يا هڪ استثنا اڇلائي ٿو. اهو هڪ بلاڪ ۾ ائين ڪرڻ آسان آهي 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 is the finally block!");
       if (reader != null) {
           reader.close();
       }
   }
}
ھاڻي اسان کي پڪ آھي ته اسان قبضي ڪيل وسيلن جو خيال رکيو آھي، قطع نظر ته پروگرام ھلڻ دوران ڇا ٿئي :) اھو سڀ ڪجھ نه آھي توھان کي استثناءَ بابت ڄاڻڻ جي ضرورت آھي. پروگرامنگ ۾ غلطي کي سنڀالڻ هڪ تمام اهم موضوع آهي: هڪ کان وڌيڪ آرٽيڪل ان لاءِ وقف ٿيل آهي. ايندڙ سبق ۾ اسين سيکارينداسين ته ڪھڙي قسم جا استثنا آھن ۽ پنھنجو استثنا ڪيئن ٺاھيو :) اُتي ملنداسين!
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION