CodeGym /جاوا بلاگ /Random-UR /جاوا میں استثنیٰ ہینڈلنگ
John Squirrels
سطح
San Francisco

جاوا میں استثنیٰ ہینڈلنگ

گروپ میں شائع ہوا۔
ہائے! آج ہم جاوا میں مستثنیٰ ہینڈلنگ پر گہری نظر ڈالیں گے۔ مجھے اس کا ذکر کرنے سے نفرت ہے، لیکن پروگرامر کے کام کا ایک بہت بڑا حصہ غلطیوں سے نمٹ رہا ہے۔ اکثر، اس کا اپنا۔ یہ پتہ چلتا ہے کہ کوئی لوگ نہیں ہیں جو غلطیاں نہیں کرتے ہیں. اور اس طرح کے کوئی پروگرام بھی نہیں ہیں۔ بلاشبہ، ایک غلطی سے نمٹنے کے دوران، اہم چیز اس کی وجہ کو سمجھنا ہے. اور بہت سی چیزیں پروگرام میں کیڑے پیدا کر سکتی ہیں۔ کسی موقع پر، جاوا کے تخلیق کاروں نے خود سے پوچھا کہ ممکنہ پروگرامنگ کی غلطیوں کے ساتھ کیا کیا جائے؟ ان سے مکمل طور پر گریز کرنا حقیقت پسندانہ نہیں ہے، پروگرامرز ایسی چیزیں لکھنے کے قابل ہوتے ہیں جس کا آپ تصور بھی نہیں کر سکتے۔ :) لہذا، ہمیں زبان کو غلطیوں کے ساتھ کام کرنے کا طریقہ کار دینے کی ضرورت ہے۔ دوسرے الفاظ میں، اگر آپ کے پروگرام میں کوئی خرابی ہے، تو آپ کو اس کے لیے کسی قسم کی اسکرپٹ کی ضرورت ہے کہ آگے کیا کرنا ہے۔ جب کوئی غلطی ہوتی ہے تو پروگرام کو بالکل کیا کرنا چاہئے؟ آج ہم اس طریقہ کار سے واقف ہوں گے۔ اسے جاوا میں مستثنیات کہا جاتا ہے ۔

ایک استثناء کیا ہے؟

ایک استثناء ایک غیر معمولی، غیر منصوبہ بند صورت حال ہے جو اس وقت ہوتی ہے جب کوئی پروگرام چل رہا ہو۔ بہت سی مستثنیات ہیں۔ مثال کے طور پر، آپ نے کوڈ لکھا ہے جو فائل سے متن پڑھتا ہے، اور پہلی لائن دکھاتا ہے۔
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. آؤٹ پٹ: تھریڈ "main" java.io.FileNotFoundException میں استثناء: C:\Users\Username\Desktop\test.txt (نظام مخصوص راستہ تلاش نہیں کر سکتا) جاوا میں، ہر ایک استثناء کو الگ کلاس کے ذریعے ظاہر کیا جاتا ہے۔ یہ تمام استثنائی کلاسیں ایک مشترکہ "آباؤ اجداد" یعنی Throwableپیرنٹ کلاس سے اخذ ہوتی ہیں۔ استثنائی طبقے کا نام عام طور پر اختصار کے ساتھ ظاہر کرتا ہے کہ استثنا کیوں ہوا:
  • FileNotFoundException(فائل نہیں ملی)

  • ArithmeticException(ریاضی کے آپریشن کے دوران ایک استثناء واقع ہوا)

  • ArrayIndexOutOfBoundsException(انڈیکس صف کی حدود سے باہر ہے)۔ مثال کے طور پر، یہ استثناء اس وقت ہوتا ہے جب آپ کسی صف کی پوزیشن 23 ظاہر کرنے کی کوشش کرتے ہیں جس میں صرف 10 عناصر ہوتے ہیں۔
مجموعی طور پر، جاوا میں تقریباً 400 ایسی کلاسیں ہیں! اتنے کیوں؟ پروگرامرز کے ساتھ کام کرنے کے لیے انہیں مزید آسان بنانے کے لیے۔ اس کا تصور کریں: آپ ایک پروگرام لکھتے ہیں، اور جب یہ چلتا ہے تو یہ ایک استثناء پیدا کرتا ہے جو اس طرح لگتا ہے:
Exception in thread "main"
اہہہ :/ اس سے زیادہ مدد نہیں ملتی۔ یہ واضح نہیں ہے کہ غلطی کا کیا مطلب ہے یا یہ کہاں سے آئی ہے۔ یہاں کوئی مفید معلومات نہیں ہے۔ لیکن جاوا میں استثنائی کلاسوں کی بڑی قسم پروگرامر کو سب سے اہم چیز دیتی ہے: غلطی کی قسم اور اس کی ممکنہ وجہ (کلاس کے نام میں سرایت)۔ یہ دیکھنے کے لئے ایک اور چیز ہے۔
Exception in thread "main" java.io.FileNotFoundException: C:\Users\Username\Desktop\test.txt (The system cannot find the specified path)
یہ فوری طور پر واضح ہو جاتا ہے کہ مسئلہ کیا ہو سکتا ہے اور مسئلے کو حل کرنے کے لیے کہاں سے کھدائی شروع کی جائے! مستثنیات، جیسے کسی بھی کلاس کی مثالیں، آبجیکٹ ہیں۔

جاوا میں مستثنیات کو پکڑنا اور ہینڈل کرنا

جاوا میں کوڈ کے خصوصی بلاکس ہیں جو مستثنیات کو سنبھالنے کے ساتھ کام کرنے کے لیے ہیں: 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!");
   }
}
آؤٹ پٹ: تھریڈ "main" 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-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بلاکس لکھے ہیں۔ اگر ایک بلاک FileNotFoundExceptionمیں ہوتا ہے try، تو پہلے catchبلاک کو عمل میں لایا جائے گا۔ اگر ایسا ArithmeticExceptionہوتا ہے تو، دوسرا بلاک عمل میں لایا جائے گا۔ catchاگر آپ چاہیں تو 50 بلاکس لکھ سکتے ہیں ۔ یقینا، بہتر ہے کہ ایسا کوڈ نہ لکھیں جو 50 مختلف قسم کے مستثنیات کو پھینک سکتا ہے۔ :) تیسرے. آپ کو کیسے پتہ چلے گا کہ آپ کا کوڈ کون سے مستثنیات پھینک سکتا ہے؟ ٹھیک ہے، آپ ان میں سے کچھ کا اندازہ لگا سکتے ہیں، لیکن آپ کے لیے ہر چیز کو اپنے سر میں رکھنا ناممکن ہے۔ جاوا کمپائلر اس لیے سب سے عام مستثنیات اور ان حالات کو جانتا ہے جہاں وہ واقع ہو سکتے ہیں۔ مثال کے طور پر، اگر آپ کوڈ لکھتے ہیں جس کے بارے میں کمپائلر جانتا ہے کہ وہ دو طرح کی مستثنیات دے سکتا ہے، تو آپ کا کوڈ اس وقت تک مرتب نہیں ہوگا جب تک کہ آپ انہیں ہینڈل نہ کریں۔ ہم ذیل میں اس کی مثالیں دیکھیں گے۔

اب Exception ہینڈلنگ کے بارے میں کچھ الفاظ

جاوا میں مستثنیات سے نمٹنے کے 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