Why are strings immutable in Java? | چرا رشته ها در جاوا تغییر ناپذیرند؟
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
-
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 میتوانند بدون نگرانی از تغییر همزمان داده، از یک رشته استفاده کنند.
