0Pricing
Java Academy · درس

لماذا تكون السلاسل غير قابلة للتغيير

افهموا عدم قابلية السلاسل للتغيير

لماذا تكون السلاسل غير قابلة للتغيير درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

السلاسل النصية لا تتغير

في Java، تكون String غير قابلة للتغيير: فبمجرد إنشائها، لا يمكن تغيير محارفها. وأي أسلوب يبدو أنه يعدّل سلسلة نصية يُرجع فعليًا سلسلة نصية جديدة تمامًا.

الأساليب تُرجع سلاسل نصية جديدة

لا تعدّل toUpperCase() وreplace() وغيرهما السلسلة الأصلية. بل تنتج String جديدة وتترك الأصل دون تغيير.

public class Main {
    public static void main(String[] args) {
        String original = "hello";
        String upper = original.toUpperCase();
        System.out.println("original: " + original);
        System.out.println("upper: " + upper);
    }
}

إعادة الإسناد ليست تغييرًا

عند كتابة s = s + "!"، يشير المتغير الآن إلى سلسلة نصية جديدة. ويبقى كائن السلسلة القديم دون تغيير، وقد تجمعه أداة جمع القمامة.

public class Main {
    public static void main(String[] args) {
        String s = "hi";
        String firstRef = s;
        s = s + "!";
        System.out.println("s: " + s);
        System.out.println("firstRef: " + firstRef);
    }
}

لماذا عدم القابلية للتغيير؟

يوفر عدم القابلية للتغيير فوائد حقيقية:

  • الأمان مع الخيوط: يمكن مشاركة السلاسل النصية دون أقفال
  • التخزين المؤقت: تبقى رموز التجزئة وإدخالات التجمع صالحة
  • الأمان: لا يمكن لأسلوب يستقبل سلسلة نصية أن يغيّرها دون علمكم

تجمع السلاسل النصية

يمكن للثوابت النصية المتطابقة أن تشترك في كائن واحد ضمن تجمع السلاسل النصية. وهذا آمن فقط لأن السلاسل النصية لا تتغير أبدًا. في المثال، يشير ثابتان نصيان إلى الكائن نفسه في التجمع.

public class Main {
    public static void main(String[] args) {
        String a = "java";
        String b = "java";
        System.out.println(a == b);
        System.out.println(a.equals(b));
    }
}

new String يكسر التجميع

يؤدي استخدام new String(...) إلى إنشاء كائن منفصل، لذلك تختلف مساواة المراجع رغم تطابق المحتوى. قارنوا المحتوى دائمًا باستخدام equals.

public class Main {
    public static void main(String[] args) {
        String a = "java";
        String b = new String("java");
        System.out.println("== : " + (a == b));
        System.out.println("equals: " + a.equals(b));
    }
}

تكلفة ضم السلاسل النصية

ينشئ كل استخدام للرمز + مع السلاسل النصية كائنًا جديدًا. ويؤدي ذلك داخل حلقة إلى تخصيص عدد كبير من السلاسل النصية قصيرة العمر، مما يهدر الوقت والذاكرة.

public class Main {
    public static void main(String[] args) {
        String result = "";
        for (int i = 1; i <= 5; i++) {
            result = result + i;
        }
        System.out.println(result);
    }
}

النمو التربيعي

بما أن كل عملية ضم تنسخ جميع المحارف السابقة، فإن إنشاء سلسلة نصية طويلة باستخدام + داخل حلقة يتوسع بشكل سيئ، تقريبًا وفق O(n squared). وهذه هي المشكلة الأساسية في الأداء.

public class Main {
    public static void main(String[] args) {
        String s = "";
        for (int i = 0; i < 1000; i++) {
            s += "x";
        }
        System.out.println("Length: " + s.length());
    }
}

القيم غير القابلة للتغيير يمكن التنبؤ بها

يُعد تمرير سلسلة نصية إلى أسلوب آمنًا؛ إذ لا يستطيع الأسلوب تغيير نسختكم. في المثال، ينشئ الأسلوب سلسلة نصية جديدة، بينما تبقى قيمة المستدعي سليمة.

public class Main {
    static void shout(String s) {
        s = s + "!!!";
        System.out.println("inside: " + s);
    }
    public static void main(String[] args) {
        String msg = "hello";
        shout(msg);
        System.out.println("outside: " + msg);
    }
}

لمحة عن الحل

عندما تحتاجون إلى إنشاء سلاسل نصية بكفاءة، توفر Java الفئة المرافقة القابلة للتغيير StringBuilder. فهي تعدّل المحتوى في مكانه بدلًا من تخصيص كائنات جديدة في كل مرة.

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 5; i++) {
            sb.append(i);
        }
        System.out.println(sb.toString());
    }
}

مقارنة النهجين

بالنسبة إلى بضع عمليات ضم، يُعد + مناسبًا تمامًا وسهل القراءة. أما عند إجراء عمليات كثيرة داخل حلقة، ففضلوا StringBuilder. اختاروا النهج بناءً على حجم النص الذي تنشئونه.

public class Main {
    public static void main(String[] args) {
        String simple = "a" + "b" + "c";
        StringBuilder sb = new StringBuilder("a");
        sb.append("b").append("c");
        System.out.println(simple);
        System.out.println(sb);
    }
}

تحقق سريع

ماذا يحدث فعليًا عند استدعاء s.toUpperCase() على كائن من النوع String؟

خلاصة

لقد تعلمتم سبب عدم قابلية السلاسل النصية للتغيير:

  • لا يتغير محتوى String أبدًا
  • تُرجع الأساليب سلاسل نصية جديدة
  • يتيح عدم القابلية للتغيير الأمان مع الخيوط والتجميع والأمان
  • يتوسع الضم باستخدام + داخل الحلقات بشكل سيئ
  • يمثل StringBuilder الحل القابل للتغيير

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

هل درس «لماذا تكون السلاسل غير قابلة للتغيير» مجاني؟

نعم — نص درس «لماذا تكون السلاسل غير قابلة للتغيير» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «لماذا تكون السلاسل غير قابلة للتغيير»؟

افهموا عدم قابلية السلاسل للتغيير تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «لماذا تكون السلاسل غير قابلة للتغيير»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا تكون السلاسل غير قابلة للتغيير
  2. بناء السلاسل باستخدام StringBuilder
  3. طرائق StringBuilder
  4. StringBuilder مقابل StringBuffer
← العودة إلى Java Academy