إنشاء النصوص، دمجها، طولها، استخراج الحروف، وأهم نقطة: المقارنة الصحيحة باستخدام equals بدل ==.
ما هو String ولماذا هو مختلف؟
النصوص (Strings) من أكثر الأشياء استخدامًا في أي برنامج — أسماء، رسائل، كلمات مرور، عناوين. في Java نمثّل النص بالنوع String.
لكن String في Java ليس نوعاً بدائياً كـ int أو double — بل هو كائن (Object). وهذا يجعل المقارنة بين النصوص مختلفة تماماً عن مقارنة الأرقام — وهو أكثر خطأ يقع فيه المبتدئون!
int, double, boolean
أنواع بدائية — تُخزَّن مباشرةً كقيم. المقارنة بـ ==
String
كائن (Object) — يُخزَّن في الذاكرة بطريقة مختلفة. المقارنة بـ .equals()
إنشاء String ودمج النصوص
إنشاء String بسيط — نضع النص بين علامتي اقتباس مزدوجتين:
// إنشاء نصوص String firstName = "Ahmed"; String lastName = "Ali"; // دمج النصوص باستخدام + String fullName = firstName + " " + lastName; System.out.println(fullName); // دمج نص مع رقم int age = 25; System.out.println("اسمي " + firstName + " وعمري " + age);
Ahmed Ali اسمي Ahmed وعمري 25
علامة + مع النصوص تعني دمج وليس جمعاً رياضياً. إذا كتبت "5" + "3" الناتج "53" وليس 8!
أهم الدوال المدمجة في String
String في Java يأتي مع دوال مدمجة كثيرة جداً — إليك أهمها:
.length() عدد الحروف في النص String name = "Ahmed";System.out.println(name.length()); ← 5 .charAt(i) الحرف عند الفهرس i (يبدأ من 0) System.out.println(name.charAt(0)); ← ASystem.out.println(name.charAt(4)); ← d [0][1][2][3][4].toUpperCase() تحويل لحروف كبيرة System.out.println(name.toUpperCase()); ← AHMEDSystem.out.println(name.toLowerCase()); ← ahmed .contains() هل النص يحتوي على كلمة معينة؟ String email = "ahmed@gmail.com";System.out.println(email.contains("gmail")); ← true .trim() إزالة المسافات من الطرفين String s = " Hello ";System.out.println(s.trim()); ← "Hello" .substring() استخراج جزء من النص String name = "Ahmed Ali";System.out.println(name.substring(0, 5)); ← "Ahmed" أهم نقطة — مقارنة النصوص: equals بدل ==
أكثر خطأ شائع في Java!
مقارنة النصوص باستخدام == قد تعطيك نتائج خاطئة ومربكة.
لفهم السبب، يجب أن تعرف أن == في Java تقارن عناوين الذاكرة وليس المحتوى:
تشبيه بسيط جداً:
تخيّل كتابَين، كلاهما يحتوي نفس النص "Hello".
== يسأل: "هل هذان نفس الكتاب المادي؟" — الجواب لا.
.equals() يسأل: "هل محتوى الكتابين متطابق؟" — الجواب نعم.
String a = new String("test"); String b = new String("test"); // == يقارن العناوين — قد يكون false! System.out.println(a == b); ← false // equals يقارن المحتوى — دائماً صحيح System.out.println(a.equals(b)); ← true ✅ // مقارنة بدون حساسية للحروف System.out.println(a.equalsIgnoreCase("TEST")); ← true ✅
❌ لا تستخدم == للنصوص
if (answer == "yes") { // قد لا يعمل صح!} ✅ استخدم equals دائماً
if (answer.equals("yes")) { // يعمل دائماً بشكل صحيح} 📋 القاعدة الذهبية
| نوع البيانات | طريقة المقارنة | مثال |
|---|---|---|
| أعداد (int, double) | == | 5 == 5 |
| نصوص (String) | .equals() | a.equals(b) |
| نصوص (بدون حساسية) | .equalsIgnoreCase() | a.equalsIgnoreCase("YES") |
مثال عملي — تطبيق كامل
نطبّق ما تعلمناه في مثال واقعي — التحقق من كلمة مرور ومعالجة إدخال المستخدم:
String username = " Ahmed "; String password = "java123"; // إزالة المسافات الزائدة username = username.trim(); // التحقق من اسم المستخدم if (username.equals("Ahmed")) { System.out.println("اسم المستخدم صحيح ✅"); } // التحقق من كلمة المرور if (password.length() >= 6) { System.out.println("كلمة المرور قوية ✅"); } else { System.out.println("كلمة المرور ضعيفة ❌"); } // طباعة معلومات System.out.println("الاسم: " + username.toUpperCase()); System.out.println("طول الاسم: " + username.length() + " حروف");
اسم المستخدم صحيح ✅ كلمة المرور قوية ✅ الاسم: AHMED طول الاسم: 5 حروف
أخطاء شائعة في String ⚠️
كتابة string بحرف صغير
❌ خطأ تجميع
string name = "Ahmed"; ✅ صحيح — S كبيرة
String name = "Ahmed"; مقارنة النصوص بـ == بدل equals
❌ غير موثوق
if (a == b) ✅ دائماً صحيح
if (a.equals(b)) نسيان علامات الاقتباس
❌ خطأ
String name = Ahmed; ✅ صحيح
String name = "Ahmed"; استدعاء دالة على null
❌ NullPointerException
String name = null; name.length(); // خطأ — name فارغة! تحقق أن المتغير ليس null قبل استدعاء أي دالة
مفهوم جوهري من خبرتي: النصوص غير قابلة للتغيير
إضافةً إلى قاعدة المقارنة بـ equals التي تعلّمتها، هناك حقيقة عميقة عن String في Java أنصحك بفهمها مبكرًا لأنها تفسّر سلوكًا قد يحيّرك: النصوص في Java غير قابلة للتغيير (Immutable).
معنى هذا أنك حين "تعدّل" نصًا — مثلًا تحوّله لأحرف كبيرة — فأنت في الحقيقة لا تغيّر الأصل، بل تُنشئ نصًا جديدًا. النص الأصلي يبقى كما هو. لهذا إذا استدعيت دالة تحويل ولم تخزّن ناتجها في متغيّر، فلن يتغيّر شيء — وهذا خطأ يقع فيه كثير من المبتدئين.
نصيحة عملية من تجربتي: إن احتجت بناء نص طويل بدمج أجزاء كثيرة داخل حلقة، فلا تدمج بـ + مرارًا لأنه ينشئ نصًا جديدًا في كل مرة ويبطئ البرنامج. استخدم StringBuilder المصمّم لهذا الغرض. لن تحتاجه الآن، لكن تذكّره حين يكبر مشروعك.
📋 ملخص الدرس
String كائن (Object) — يبدأ بحرف كبير دائماً
الدمج بـ + — والمقارنة بـ .equals()
length() للطول و charAt(i) لاستخراج حرف
trim() و toUpperCase() و contains()
⏭️ في الدرس القادم:
سنطبّق كل ما تعلمناه في مشروع صغير متكامل يجمع المتغيرات، الشروط، الحلقات، الدوال، والكلاسات معاً — لترى كيف تعمل جميع المفاهيم في برنامج حقيقي! 🚀