غیرقابل تغییر بودن (Immutability) در جاوا (جشنواره عید تا عید)

(این مقاله از طرف جناب آقای مهدی حسین زاده سامانی برای جشنواره عید تا عید جاواکاپ ارسال شده است و محتوای این مطلب لزوماً موردتأیید جاواکاپ نیست. لطفاً با مطالعه، بازنشر و امتیازدهی به این مطلب، به انتخاب برترین مقاله در این جشنواره کمک نمایید.)
به شی[1]ای غیرقابلتغییر (immutable) گفته میشود که بعد از ساخته شدن شیء، نتوانیم به هیچ طریقی حالت و یا مقادیر آن شیء را تغییر بدهیم. این ویژگی برای یک آبجکت چندین مزیت دارد. مثلا این که در برنامههایی که concurrency و چندین ترد[2] وجود داشته باشد، اگر چند ترد همزمان باهم برای نوشتن اقدام کنند امکان خراب شدن شیء وجود ندارد و یا هنگام خواندن مقدار متغیرهای شیء توسط یک ترد اطمینان داریم که مقدار آنها پایدار است.
یکی دیگر از مزیتهای شیءهای غیرقابلتغییر این است که میشود در مصرف حافظه صرفهجویی کرد و سرعت اجرا را هم بالا برد. مثلا کلاس String که نمونهای از کلاسهای immutable هست را در نظر بگیرید. به دو روش میتوانیم یک استرینگ جدید بسازیم (در اینجا “Ali” مقدار دلخواهی است):
String name = “Ali”; String name = new String (“Ali”);
در صورتی که استرینگ را به روش اول بسازیم، جدای از این که هم نوشتن عبارت سادهتر است و هم احتمالا خوانایی آن در برنامه بیشتر است، در زمان اجرا، اگر از قبل استرینگی با مقدار “Ali” در برنامه (یا همان heap جاوا) موجود نباشد، یک شیء جدید از نوع استرینگ با مقدار “Ali” ساخته شده و متغیر name به آن اشاره داده میشود (انتظاری هم جز این نداشتیم!). سپس این شیء در Constant Pool هیپ کش میشود که دلیل این کار را در حالت دوم میفهمیم. در حالت دوم، یعنی زمانی که از قبل استرینگی با مقدار “Ali” موجود بوده است، جاوا این متغیر جدید (name) را به همان استرینگ ازقبلموجود (در Constant Pool هیپ جاوا) اشاره میدهد یعنی دیگر شیء جدیدی ساخته نمیشود که این کار علاوه بر صرفهجویی در مصرف حافظه، سرعت اجرا را هم خیلی بالاتر میبرد.
ممکن است بگویید که ما میتوانیم مقدار استرینگ را تغییر دهیم یعنی به طور مثال میتوانیم بنویسیم:
name = “Hossein”;
نکتهی جالب در همینجا است که شما هر وقت (به فرض خودتان) مقدار یک استرینگ را تغییر میدهید، در واقع دقیقا همان کار شمارهی 1 بالا انجام میشود یعنی در هر تغییر، یک شیء جدید ساخته میشود به عبارت دقیقتر، در صورت وجود استرینگ دیگری با مقدار “Hossein”، متغیر name به آن اشاره داده میشود و در صورت عدم وجود، یک شیء جدید با مقدار “Hossein” ساخته میشود. در پایان بگوییم که نحوهی ساخت این نوع شیها به راحتی در اینترنت پیدا میشود.
[1] Object
[2] Thread