String類在Java中被設計成不可變的,這是Java開發人員大家都知道的事情。但是要讓大家真的說出來為什么String在Java中是不可變的,有時候真的能讓人一時語塞,或者說的不夠全面。這個問題有各種提問的方式,例如:“為什么Java中要把String類設計成不可變的?”,“String類被設計成不可變類有什么好處?”基本上都是一個思路。
接下來個人從以下幾個方面來談談自己對這個問題的看法:
什么是不可變?
《EffectiveJava》中對于不可變類的解釋如下:
不可變類只是其實例不能被修改的類。每個實例中包含的所有信息都必須在創建該實例的時候就提供,并且在對象的整個生命周期內固定不變。為了使類不可變,要遵循下面五條規則:
1.不要提供任何會修改對象狀態的方法。
2.保證類不會被擴展。一般的做法是讓這個類稱為的,防止子類化,破壞該類的不可變行為。
3.使所有的域都是final的。
4.使所有的域都成為私有的。防止客戶端獲得訪問被域引用的可變對象的權限,并防止客戶端直接修改這些對象。
5.確保對于任何可變性組件的互斥訪問。如果類具有指向可變對象的域,則必須確保該類的客戶端無法獲得指向這些對象的引用。
不可變帶來的好處
- 多線程安全:不可變對象天生多線程安全。因為不可變對象不會被改變,所以它們可以被多線程共享,不需要增加額外的同步操作。
- 字符串池:
上面的代碼只會創建一個對象實例到JavaHeap中,當創建str1時候,會去字符串池中查看是否已經有了這個字符串,如果有,那么把str1的引用直接指向這個字符串實例上去,這樣便極大的節省了內存空間的使用。如果字符串可變的話,那么修改了其中一個對象,就會影響另外一個。
緩存HashCode
- String類是基石
正是因為有了以String類為代表的這些不可變類,才能為其他對象的構建提供了極大的便利,想想我們在編寫Java程序的時候,是不是大量的使用了String類。
以上,就是我個人對Java中為什么String類是不可變的幾點看法,大家還有什么更好的見解?歡迎討論交流,批評指正~