مقدمة: لماذا حتى العباقرة يخطئون في Java؟
\n\nJava لغة صارمة ولكنها مجزية. ومع ذلك، غالبًا ما يتعثر المبتدئون في نفس الأخطاء المتكررة. وفقًا لإحصائيات Stack Overflow، فإن 70% من أسئلة مطوري Java المبتدئين تتعلق بخمسة أخطاء كلاسيكية. في هذه المقالة، جمعنا "أهم أخطاء مطوري Java المبتدئين: من الألف إلى الياء" - من الخلط بين == إلى التعامل غير الصحيح مع الذاكرة.
سنحلل كل مشكلة بأمثلة، حتى لا تحفظ القاعدة فحسب، بل تفهم جوهرها. هيا بنا!
\n\n1. الخطأ رقم 1: استخدام "==" بدلاً من equals() - كلاسيكي من نوعه
\n\nالخطأ الأكثر شيوعًا هو مقارنة السلاسل النصية باستخدام ==. يعتقد المبتدئون أن هذا يعمل، ثم يتفاجأون لماذا "Java" == "Java" يعطي false.
لماذا يحدث هذا؟
\n- \n
==يقارن المراجع إلى الكائنات (العناوين في الذاكرة). \n equals()يقارن محتويات الكائنات. \n
مثال:
\n\nString a = new String("Java");\nString b = new String("Java");\n\nSystem.out.println(a == b); // false — كائنات مختلفة في الكومة\nSystem.out.println(a.equals(b)); // true — محتوى متطابق\n\n\nنصيحة: استخدم دائمًا .equals() للسلاسل النصية. بالنسبة للأنواع البدائية (int, double) — يعمل == بشكل صحيح.
2. الخطأ رقم 2: نسيان NullPointerException
\n\nNullPointerException (NPE) هو أسوأ عدو للمبتدئين. يحدث غالبًا عند استدعاء دالة على كائن null.
سيناريو نموذجي:
\n\npublic String getName(User user) {\n return user.getName().toUpperCase(); // إذا كان user == null — يحدث NPE!\n}\n\n\nكيف نصلحه؟ استخدم البرمجة الدفاعية:
\n\npublic String getName(User user) {\n if (user == null) {\n return "Unknown";\n }\n return user.getName().toUpperCase();\n}\n\n\nأو، بدءًا من Java 8، استخدم Optional:
public String getName(User user) {\n return Optional.ofNullable(user)\n .map(u -> u.getName().toUpperCase())\n .orElse("Unknown");\n}\n\n\n3. الخطأ رقم 3: تجاهل الاستثناءات
\n\nكتل catch الفارغة هي نمط سيء. الخطأ لا يختفي، أنت فقط تخفيه.
كود سيء:
\n\ntry {\n int result = 10 / 0;\n} catch (ArithmeticException e) {\n // لا نفعل شيئًا — يتم ابتلاع الخطأ بصمت\n}\n\n\nكود جيد:
\n\ntry {\n int result = 10 / 0;\n} catch (ArithmeticException e) {\n System.err.println("خطأ في القسمة على صفر: " + e.getMessage());\n // أو إعادة رمي الاستثناء\n throw new RuntimeException("خطأ حرج", e);\n}\n\n\n4. الخطأ رقم 4: التعامل غير الصحيح مع المجموعات
\n\nغالبًا ما يخلط المبتدئون بين List و Set و Map، وينسون أيضًا الأدوية العامة (Generics).
أخطاء نموذجية:
\n\n- \n
- استخدام الأنواع الخام (raw types) —
List list = new ArrayList();\n - تعديل المجموعة أثناء التكرار بدون
Iterator.remove()\n - استبدال
HashMapبـTreeMapدون فهم الفرق \n
النهج الصحيح:
\n\nList<String> names = new ArrayList<>();\nnames.add("Alice");\nnames.add("Bob");\n\n// الحذف أثناء التكرار\nIterator<String> iterator = names.iterator();\nwhile (iterator.hasNext()) {\n String name = iterator.next();\n if (name.equals("Alice")) {\n iterator.remove(); // آمن\n }\n}\n\n\n5. الخطأ رقم 5: تسرب الذاكرة وعدم إغلاق الموارد بشكل صحيح
\n\nتنسى إغلاق Scanner أو FileInputStream أو الاتصال بـ