Farzad Afi Logo

FarzadAfi

آموزش تخصصی برنامه نویسی

Why are strings immutable in Java? | چرا رشته ها در جاوا تغییر ناپذیرند؟

📖توضیحات درس

🎥 این ویدیو قسمت بیست و هشتم از بوت‌کمپ رایگان جاواست. 🔒 چرا رشته‌ها در جاوا تغییرناپذیرند؟ (String Immutability) 📝 در این قسمت به یکی از ویژگی‌های مهم کلاس String در جاوا می‌پردازیم: تغییرناپذیری (Immutability 💡 بررسی می‌کنیم که تغییرناپذیری دقیقاً به چه معناست و چرا رشته‌ها در جاوا به‌صورت تغییرناپذیر طراحی شده‌اند. ⚙️ در ادامه یاد می‌گیریم: • مفهوم Immutable Object چیست • چرا کلاس String قابل تغییر نیست • این ویژگی چگونه باعث صرفه‌جویی در حافظه می‌شود • تغییرناپذیری چگونه امنیت و پایداری داده‌ها را افزایش می‌دهد 🔍 با بررسی نحوه کار رشته‌ها در String Pool و رفتار آن‌ها در حافظه، درک عمیق‌تری از طراحی داخلی جاوا به دست می‌آوریم. ✅ در پایان جلسه، همه نکات کلیدی را مرور می‌کنیم تا درک کاملی از **اهمیت و کاربرد تغییرناپذیری رشته‌ها در جاوا** داشته باشیم. 👥 گروه پرسش و پاسخ تلگرام: @programmingByFarzadAfi 💬 گروه پرسش و پاسخ بله: @programming_by_farzadafi ❓ هر سوالی داشتی می‌تونی در گروه بپرسی؛ من یا مربی‌های گروه کمکت می‌کنیم. 🚀 بوت‌کمپ رایگان جاوا – آموزش پروژه‌محور برای یادگیری عمیق و ورود به بازار کار.
00:18:28🎯رایگان

📄جزوه

مفاهیم کلیدی

  • Immutable: به اشیائی گفته می‌شود که پس از ایجاد در حافظه، وضعیت یا مقدار آن‌ها قابل تغییر نیست. در جاوا، کلاس String به صورت Immutable طراحی شده است.

  • String Pool: یک ناحیه اختصاصی در حافظه (Heap) که جاوا رشته‌های ایجاد شده را در آن ذخیره می‌کند تا در صورت تعریف رشته‌های مشابه، به جای ایجاد آبجکت جدید، از همان نمونه قبلی استفاده شود.

  • Reference: متغیری که به آدرس یک آبجکت در حافظه اشاره می‌کند. در رشته‌ها، تغییر مقدار متغیر به معنای تغییر آدرسِ اشاره‌گر به یک آبجکت جدید است، نه تغییر محتوای آبجکت قبلی.

نکات مهم مصاحبه‌ای**

  • چرا String در جاوا تغییرناپذیر (Immutable) است؟

اصلی‌ترین دلایل آن صرفه‌جویی در مصرف حافظه (از طریق String Pool) و امنیت (جلوگیری از تغییر ناخواسته داده‌ها در متدها و Threadهای مختلف) است.

  • تفاوت تعریف رشته به صورت Literal با استفاده از کلمه کلیدی new چیست؟

وقتی رشته به صورت Literal (مثلاً "test") تعریف شود، در String Pool قرار می‌گیرد. اما استفاده از new String() باعث ایجاد یک آبجکت جدید در خارج از String Pool می‌شود که باعث هدررفت حافظه می‌گردد.

  • در صورت الحاق (Concatenation) مداوم رشته‌ها در یک حلقه، چه اتفاقی برای حافظه می‌افتد؟

به دلیل Immutable بودن، در هر بار تغییر، یک آبجکت جدید در حافظه ساخته می‌شود. این کار باعث نوسان شدید در حافظه و درگیر شدن مداوم Garbage Collector می‌شود که کارایی برنامه را کاهش می‌دهد.

  • چرا استفاده از String در حلقه‌های طولانی توصیه نمی‌شود؟

چون در هر تکرار، یک آبجکت جدید ساخته شده و حافظه اشغال می‌شود که این امر باعث افت عملکرد سیستم می‌شود.

  • عملگر == در مقایسه دو رشته چه چیزی را بررسی می‌کند؟

این عملگر رفرنس (آدرس حافظه) دو رشته را مقایسه می‌کند. اگر دو رشته در String Pool باشند و مقدار یکسانی داشته باشند، نتیجه true و اگر یکی با new ایجاد شده باشد، نتیجه false خواهد بود.

  • نقش امنیت در تغییرناپذیری رشته‌ها چیست؟

از آنجایی که رشته‌ها به عنوان پارامتر در بسیاری از موارد حساس (مثل نام کاربری، پسورد، آدرس شبکه) استفاده می‌شوند، تغییرناپذیری آن‌ها مانع از آسیب‌پذیری‌های امنیتی و تغییرات ناخواسته داده در حین اجرای برنامه می‌شود.

مثال یا سناریوی کاربردی

سناریوی امنیت در تراکنش بانکی: فرض کنید متدی برای واریز وجه دارید که نام صاحب حساب را به عنوان String دریافت می‌کند. ابتدا برنامه نام را اعتبار سنجی می‌کند (مثلاً بررسی وجود حساب برای نام "فرزاد"). اگر رشته‌ها قابل تغییر (Mutable) بودند، ممکن بود در فاصله زمانی بین تایید نام و انجام عملیات واریز، مقدار آن رشته در بخش دیگری از برنامه به "علی" تغییر کند. در این حالت، تاییدیه برای "فرزاد" صادر شده اما پول به حساب "علی" واریز می‌شود. تغییرناپذیری String تضمین می‌کند که داده پس از تایید، بدون تغییر باقی می‌ماند.

بیشتر بدانید

  • IDE Tip در محیط IntelliJ IDEA، اگر از new String() برای تعریف یک رشته ساده استفاده کنید، محیط توسعه به شما هشدار (Warning) می‌دهد که این کار اضافی است و بهتر است آن را به حالت Literal تبدیل کنید تا از مزایای String Pool بهره‌مند شوید.

  • نکته سینتکسی: برای مقایسه محتوای دو رشته (به جای آدرس حافظه)، همیشه باید از متد .equals() استفاده کرد، زیرا عملگر == ممکن است در صورت استفاده از new String() نتایج غیرمنتظره‌ای بدهد.

  • بهینه‌سازی: تغییرناپذیری باعث می‌شود که رشته‌ها به طور پیش‌فرض Thread-Safe باشند، یعنی چندین Thread می‌توانند بدون نگرانی از تغییر همزمان داده، از یک رشته استفاده کنند.