📘 شرح الدرس الوحدة 6: قراءة الأخطاء وتصحيحها · الدرس 15 من 17
الدرس 15
📋 في الخطة: الوحدة 11. قراءة وفهم رسائل الأخطاء

قراءة وفهم رسائل الأخطاء

رسالة الخطأ ليست عدوًّا: نتعلّم قراءتها كخريطة تدلّنا على مكان الخطأ ونوعه.

trymyNumbers[10] ! catch (Exception e)
بعد هذا الدرس ستستطيع أن:
  • تحدد رقم السطر ونوع الخطأ ووصفه من رسالة المترجم.
  • تقرأ رسالة الاستثناء وتتبّع المكدّس Stack Trace.
  • تترجم أشهر رسائل الأخطاء والاستثناءات إلى أسبابها.
  • تستخدم رسالة الخطأ دليلًا لتحديد الموقع الدقيق للخطأ.

١رسالة الخطأ صديقك

عندما يظهر خطأ يرتبك كثير من المبتدئين من النص الإنجليزي الطويل ويتجاهلونه. لكن رسالة الخطأ هي أهم دليل لديك: تخبرك ماذا حدث، وأين حدث، وأحيانًا لماذا. تعلّم قراءتها يوفر عليك معظم وقت التصحيح.

٢تشريح رسالة خطأ الصياغة

رسائل المترجم في NetBeans تأتي بهذا الشكل الثابت:

Main.javaاسم الملف:4:رقم السطر error:نوعها: خطأ ';' expectedالوصف: المتوقع فاصلة منقوطة
Main.java
public class Main {    public static void main(String[] args) {        int count = 3;        String msg = "عدد الطلاب " + count        System.out.println(msg);    }}
Output – JavaApplication (run)×
Main.java:4: error: ';' expected
String msg = "عدد الطلاب " + count
^
1 error
BUILD FAILED (total time: 0 seconds)

السطر الثاني من الرسالة يعرض السطر نفسه، والعلامة ^ تشير إلى المكان الذي توقف فيه المترجم، وهو هنا نهاية السطر حيث كان ينتظر ;.

٣قاموس أشهر رسائل المترجم

الرسالةمعناهاالحل المعتاد
';' expectedتتوقع فاصلة منقوطةأضف ; في نهاية الجملة
cannot find symbolاسم غير معروف: متغير أو دالة أو كلاستحقق من الإملاء وحالة الأحرف، وأن المتغير معرّف قبل استخدامه
incompatible types: String cannot be converted to intوضع قيمة من نوع في متغير من نوع آخرغيّر نوع المتغير أو حوّل القيمة
missing return statementدالة تعيد قيمة لكن لا يوجد returnأضف return بالقيمة المناسبة
variable k might not have been initializedاستخدام متغير قبل إعطائه قيمةأعطه قيمة ابتدائية مثل int k = 0;
reached end of file while parsingقوس { غير مغلقأضف } الناقصة، واستخدم Alt+Shift+F لتنسيق الكود
')' expectedقوس ) ناقصأكمل الأقواس في الشرط أو الاستدعاء
class, interface, enum, or record expectedكود خارج الكلاس، غالبًا بسبب } زائدةاحذف القوس الزائد

مثال: رسالتان في برنامج واحد

Main.java
public class Main {    static int square(int x) {        int r = x * x;    }    public static void main(String[] args) {        int k;        System.out.println(k);    }}
Output – JavaApplication (run)×
Main.java:4: error: missing return statement
}
^
Main.java:7: error: variable k might not have been initialized
System.out.println(k);
^
2 errors
BUILD FAILED (total time: 0 seconds)

الحل: أضف return r; قبل نهاية الدالة square، واكتب int k = 0;

٤تشريح رسالة خطأ زمن التنفيذ

رسالة الاستثناء أطول، لكنها منظمة. اقرأها من الأعلى:

Exception in thread "main"حدث استثناء في البرنامج الرئيسي java.lang.ArithmeticExceptionنوع الاستثناء: / by zeroالتفاصيل

بعدها تأتي أسطر تبدأ بـ at تُسمّى تتبّع المكدّس Stack Trace: تبيّن سلسلة الدوال التي كانت تعمل لحظة الخطأ. السطر الأول منها هو مكان حدوث الخطأ، والأسطر التالية هي من استدعى هذه الدالة.

Main.java
public class Main {    static double average(int total, int count) {        return total / count;    }    public static void main(String[] args) {        System.out.println("بداية البرنامج");        double a = average(250, 0);        System.out.println(a);    }}
Output – JavaApplication (run)×
run:
بداية البرنامج
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.average(Main.java:3)
at Main.main(Main.java:7)
BUILD FAILED (total time: 0 seconds)

نقرأ: الخطأ قسمة على صفر، حدث في الدالة average في السطر 3، والتي استُدعيت من main في السطر 7. إذن نصلح إما الدالة (نتحقق أن count ليس صفرًا)، أو الاستدعاء (لا نمرّر صفرًا).

عندما يبدأ التتبّع من مكتبة جافا

أحيانًا تظهر أولًا أسطر من داخل مكتبات جافا مثل java.base/java.util.Scanner. هذه ليست أخطاء في جافا، بل في طريقة استخدامنا لها. تجاوزها وابحث عن أول سطر فيه اسم ملفك مثل Main.java.

Output – JavaApplication (run)×
run:
ادخل عمرك:
عشرون
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:947)
at java.base/java.util.Scanner.next(Scanner.java:1602)
at java.base/java.util.Scanner.nextInt(Scanner.java:2267)
at java.base/java.util.Scanner.nextInt(Scanner.java:2221)
at Main.main(Main.java:6)
BUILD FAILED (total time: 0 seconds)

السطر المهم هو الأخير: Main.main(Main.java:6)، أي سطر nextInt() في برنامجنا.

٥قاموس أشهر الاستثناءات

الاستثناءمتى يحدث؟مثال
ArithmeticException: / by zeroقسمة عدد صحيح على صفر10 / 0
InputMismatchExceptionإدخال لا يطابق نوع دالة القراءةكتابة «abc» عند nextInt()
NumberFormatExceptionتحويل نص لا يمثل رقمًاInteger.parseInt("12a")
NullPointerExceptionاستخدام كائن لم يُنشأ بعد (قيمته null)استدعاء دالة من متغير قيمته null
ArrayIndexOutOfBoundsExceptionرقم خانة خارج حدود المصفوفةa[3] ومصفوفة طولها 3
StringIndexOutOfBoundsExceptionرقم حرف خارج طول النص"Ali".charAt(5)

٦التحذيرات Warnings

إلى جانب الأخطاء الحمراء يعرض NetBeans تحذيرات بلون أصفر ⚠️. التحذير لا يمنع تشغيل البرنامج، لكنه ينبهك إلى شيء غالبًا غير مقصود:

توقّع وتحقّق

في الرسالة Main.java:12: error: ';' expected في أي سطر الخطأ؟

الرقم بعد اسم الملف هو رقم السطر.

ما معنى cannot find symbol؟

المترجم لا يعرف هذا الاسم: إملاء خاطئ أو متغير غير معرّف.

في تتبّع المكدّس، أي سطر يحدد مكان الخطأ في برنامجك؟

ابحث عن أول سطر فيه Main.java.

أي استثناء يظهر عند a[5] ومصفوفة طولها 5؟

الخانات من 0 إلى 4، فالخانة 5 خارج الحدود.

الخلاصة

انتقل إلى تقييم الدرسأسئلة الاختيار، وصح وخطأ، وأكمل الفراغات، والأسئلة العملية.ابدأ التقييم ←