الاستثناءات Exceptions
نحمي البرنامج من التوقّف المفاجئ عند حدوث خطأ أثناء التشغيل، ونتعامل معه بطريقة منظّمة وآمنة.
- تميّز بين الأخطاء النحوية Syntax errors وأخطاء وقت التشغيل Runtime errors.
- تصنّف الاستثناءات إلى Checked و Unchecked و Error مع مثال لكل منها.
- تعالج الاستثناء باستخدام try و catch و finally.
- تكتب أكثر من catch مرتّبة من الأخص إلى الأعم.
١ما هو الاستثناء؟
الهدف من نظام الاستثناءات: التقاط الخطأ ومعالجته ليستمر البرنامج إلى آخر تعليمة.
| أخطاء نحوية Syntax Errors | أخطاء وقت التشغيل Runtime Errors | |
|---|---|---|
| متى تُكتشف؟ | أثناء الترجمة Compile Time | أثناء تشغيل البرنامج |
| أمثلة | نسيان الفاصلة المنقوطة، خطأ في حالة الأحرف | القسمة على صفر، عنصر غير موجود في مصفوفة |
| التعامل معها | تصحيح الكود | الاستثناءات try / catch |
٢أقسام الاستثناءات
١) Checked Exception: الاستثناء المتحقق
يتحقق منه المترجِم ويُلزمك بالتعامل معه قبل التشغيل: بـ try-catch، أو بالتصريح عنه بـ throws. أمثلة: IOException و FileNotFoundException.
package exception; import java.io.FileReader; public class Student { public static void main(String[] args) { FileReader file = new FileReader("data.txt"); } }
package exception; import java.io.FileNotFoundException;import java.io.FileReader; public class Student { public static void main(String[] args) throws FileNotFoundException { FileReader file = new FileReader("data.txt"); } }
package exception; import java.io.FileNotFoundException;import java.io.FileReader; public class Student { public static void main(String[] args) { try { FileReader file = new FileReader("data.txt"); } catch (FileNotFoundException ex) { System.out.println(ex.getMessage()); } } }
في NetBeans يقترح المصباح الحلّين: Add throws clause أو Surround Statement with try-catch.
٢) Unchecked Exception: غير المتحقق (Runtime Exception)
لا يتحقق منه المترجِم، بل يظهر وقت التشغيل، والمبرمج غير مُلزم بمعالجته. ينتج عادةً عن أخطاء منطقية:
public class Main { public static void main(String[] args) { int[] myNumbers = {1, 2, 3}; System.out.println(myNumbers[10]); // error! }}
| الجانب | Checked | Unchecked |
|---|---|---|
| وقت الفحص | أثناء الترجمة | أثناء التشغيل |
| إلزام المعالجة | إلزامي | اختياري |
| أمثلة | IOException, SQLException | NullPointerException, ArithmeticException |
٣) Error
خطأ بسبب حدود الجهاز الذي يعمل عليه البرنامج، ولا يرتبط بالبرنامج مباشرة؛ مثل امتلاء الذاكرة: «JVM is out of memory».
٣معالجة الاستثناءات: try و catch و finally
| الكتلة | وظيفتها |
|---|---|
try | نكتب فيها الكود الذي نتوقع أن يسبب خطأ؛ فإذا وقع الخطأ «ترمي» الاستثناء. |
catch | تلتقط الاستثناء الذي رمته try وتعالجه، ثم يستمر التنفيذ بعدها. |
finally | تُنفَّذ دائمًا سواء حدث استثناء أم لا؛ مثل إغلاق ملف أو اتصال بقاعدة بيانات. |
try { // الكود الذي قد يسبب استثناء}catch (Exception e) { // التعامل مع الخطأ}finally { // (اختياري) كود يتم تنفيذه دائمًا}
مثال الدرجات
package exception;import java.util.Scanner;public class Main { public static void main(String[] args) { double marks [] = {90, 88.50, 77, 100, 50}; Scanner scan = new Scanner(System.in); int idx; try { System.out.print("Enter an index number.(0 to 4): "); idx = scan.nextInt(); System.out.println("The mark is: " + marks[idx]); } catch (Exception e) { System.out.println(e); } finally { System.out.println("finally block"); } System.out.println("After try and block"); }}
أدخل 4 فيطبع الدرجة 50.0. جرّب إدخال 5 فيلتقط catch الخطأ ArrayIndexOutOfBoundsException ويكمل البرنامج.
أكثر من catch: لكل خطأ رسالة
package exception;import java.util.InputMismatchException;import java.util.Scanner;public class Main { public static void main(String[] args) { double marks [] = {90, 88.50, 77, 100, 50}; Scanner scan = new Scanner(System.in); int idx = 0; try { System.out.print("Enter an index number.(0 to 4): "); idx = scan.nextInt(); System.out.println("The mark is: " + marks[idx]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("ERROR: the number " + idx +" is out of range"); } catch(InputMismatchException e){ System.out.println("ERROR: the number you entered is not an integer number"); } catch(Exception e){ System.out.println("ERROR: " + e); } finally { System.out.println("finally block"); } System.out.println("After try and block"); }}
توقّع وتحقّق
أجب قبل أن تنظر إلى الشرح. التصحيح فوري، وإجاباتك تُحفظ.
أي كتلة تُنفَّذ دائمًا سواء حدث خطأ أم لا؟
FileNotFoundException من نوع:
نسيان الفاصلة المنقوطة:
ما الناتج إذا أدخل المستخدم 5 في مثال الدرجات الثاني؟
الخلاصة
- الاستثناء خطأ وقت التشغيل يوقف البرنامج إن لم يُعالج.
- Checked يُلزمك المترجِم بمعالجته (try-catch أو throws)، و Unchecked اختياري، و Error من الجهاز.
- try للكود المشكوك فيه، catch للمعالجة، finally دائمًا.
- عدة catch: من الأخص إلى الأعم.