تخطَّ إلى المحتوى

٨ يوليو ٢٠٢٦

حل خطأ NullPointerException في جافا بالعربي

شارك المقال:

اللقب الشهير لهذا الخطأ في عالم جافا: "خطأ المليار دولار" — وصفه مخترع مفهوم null نفسه. كل مطوّر جافا سيقابل java.lang.NullPointerException (اختصارًا NPE) مئات المرات، لذا فهمه مرة واحدة بعمق يوفّر عليك سنوات من التخمين.

ماذا يعني null أصلًا؟

المتغيّر من نوع كائن (مثل String أو ArrayList) هو إشارة إلى مكان في الذاكرة. null يعني: "هذه الإشارة لا تشير إلى أي شيء".

String name = null;      // صندوق فارغ — لا يوجد نص هنا
int len = name.length(); // 💥 NullPointerException

لا يمكنك أن تسأل "لا شيء" عن طوله — هذا كل ما يقوله الخطأ.

كيف تقرأ الـ Stack Trace

Exception in thread "main" java.lang.NullPointerException:
  Cannot invoke "String.length()" because "name" is null
	at com.shop.UserService.validate(UserService.java:42)
	at com.shop.Main.main(Main.java:15)
  • السطر الأول: منذ جافا 14 الرسالة تحدد الفاعل بالاسم — name هو الـ null.
  • UserService.java:42: أول سطر يخص كودك أنت — ابدأ منه دائمًا (تجاهل أسطر مكتبات جافا الداخلية).
  • الأسطر التالية: سلسلة الاستدعاءات التي أوصلت إلى هناك.

الأسباب الخمسة الأكثر شيوعًا

السببمثال
حقل لم يُهيَّأprivate List<String> items; ثم items.add(...)
دالة أعادت nullmap.get("مفتاح غير موجود")
ترتيب المقارنةinput.equals("نعم") وinput قد يكون null
سلسلة استدعاءات طويلةuser.getAddress().getCity().trim()
فكّ تغليف تلقائيInteger count = null; ثم int c = count;

الحلول العملية

1) أعطِ الحقول قيمة ابتدائية — امنع null من الولادة

// ❌ قنبلة موقوتة
private List<String> items;

// ✅ آمن منذ اللحظة الأولى
private List<String> items = new ArrayList<>();

القاعدة نفسها للدوال: أعِد قائمة فارغة بدل nullreturn Collections.emptyList(); تجعل كل حلقات for عند المستدعي آمنة.

2) اقلب ترتيب المقارنة

// ❌ ينفجر إذا كان input = null
if (input.equals("نعم")) { ... }

// ✅ الثابت أولًا — لا يمكن أن يكون null
if ("نعم".equals(input)) { ... }

3) فكّك السلاسل الطويلة عند التشخيص

// ❌ أي حلقة في السلسلة قد تكون null — أيها المذنب؟
String city = user.getAddress().getCity().trim();

قسّمها لأسطر منفصلة وسيقودك رقم السطر في الـ stack trace إلى المذنب مباشرة. (منذ جافا 14 الرسالة نفسها تحدده حتى في السلسلة الواحدة.)

4) استخدم Optional للقيم التي قد تغيب

عندما يكون الغياب حالة طبيعية (مستخدم غير موجود مثلًا)، أعلنها في نوع الدالة بدل مفاجأة المستدعي بـ null:

Optional<User> findUser(String email) { ... }

String name = findUser(email)
    .map(User::getName)
    .orElse("زائر");

5) افشل مبكرًا في مداخل الدوال

public void process(Order order) {
    Objects.requireNonNull(order, "order يجب ألا يكون null");
    // من هنا فصاعدًا order مضمون
}

الفشل الفوري برسالة واضحة أفضل ألف مرة من NPE غامض بعد عشرين سطرًا.

قائمة تحقّق سريعة

  • ما أول سطر في الـ stack trace يخص كودك؟ ابدأ منه.
  • من هو الـ null؟ (جافا 14+ تسمّيه في الرسالة حرفيًا)
  • هل للحقول قيم ابتدائية؟ هل تعيد دوالك قوائم فارغة بدل null؟
  • هل الثابت على يسار equals؟
  • هل الغياب حالة متوقعة؟ → استخدم Optional.

الخلاصة

NPE لا يقول "برنامجك سيّئ" بل يقول: "استدعيت شيئًا على لا شيء — في هذا السطر بالضبط". اقرأ الـ stack trace من أول سطر يخصك، سمِّ الـ null، ثم عالج المصدر لا العرَض: قيم ابتدائية، قوائم فارغة، وOptional للغياب المشروع.

أكمل رحلتك في مسار جافا بالعربي، وقارن مع الفرق بين جافا وبايثون و الفرق بين Kotlin وجافا — حيث حلّت Kotlin مشكلة null من جذورها في نظام الأنواع نفسه.

📚 مصادر رسمية للتعمّق: توثيق Java من Oracle

الأسئلة الشائعة

ما معنى null في جافا بكلمة واحدة؟

null يعني أن المتغيّر لا يشير إلى أي كائن في الذاكرة — صندوق فارغ تمامًا. وأي محاولة لاستدعاء دالة أو قراءة خاصية من هذا الفراغ ترمي NullPointerException فورًا.

كيف أعرف أي متغيّر بالضبط كان null؟

منذ جافا 14 أصبحت الرسالة تخبرك حرفيًا، مثل: Cannot invoke String.length() because name is null. في الإصدارات الأقدم، انظر لرقم السطر في أول سطر من الـ stack trace يخص كودك أنت، وافحص كل جزء فيه يسبقه نقطة.

هل أضع فحص null قبل كل سطر لأتجنب الخطأ؟

لا — الإفراط في if (x != null) يخفي المشكلة بدل حلها. الأفضل منع null من المصدر: أعطِ الحقول قيمًا ابتدائية، أعِد قوائم فارغة بدل null من الدوال، واستخدم Optional للقيم التي غيابها حالة طبيعية متوقعة.

اقرأ أيضًا

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