- Java程序員面試筆試寶典(第2版)
- 何昊等編著
- 1033字
- 2022-06-17 16:00:46
1.13 不可變類
不可變類(Immutable Class)是指當創建了這個類的實例后,就不允許修改它的值,也就是說一個對象一旦被創建出來,在其整個生命周期中,它的成員變量就不能被修改。它有點類似于常量,只允許別的程序讀,不允許別的程序進行修改。
在Java類庫中,所有基本類型的包裝類都是不可變類,例如Integer、Float等。此外,String也是不可變類。可能有人會有疑問,既然String是不可變類,為什么還可以寫出如下代碼來修改String類型的值呢?

程序運行結果為:

表面上看,好像是修改String類型對象s的值。其實不是,String s="Hello"語句聲明了一個可以指向String類型對象的引用,這個引用的名字為s,它指向了一個字符串常量"Hello"。
s+="world"并沒有改變s所指向的對象(由于"Hello"是String類型的對象,而String又是不可變量),這句代碼運行后,s指向了另外一個String類型的對象,該對象的內容為"Hello world"。原來的那個字符串常量"Hello"還存在于內存中,并沒有被改變。
在介紹完不可變類的基本概念后,下面主要介紹如何創建一個不可變類。通常來講,要創建一個不可變類需要遵循下面四條基本原則:
1)類中所有的成員變量被private所修飾。
2)類中沒有寫或者修改成員變量的方法,例如setxxx。只提供構造方法,一次生成,永不改變。
3)確保類中所有的方法不會被子類覆蓋,可以通過把類定義為final或者把類中的方法定義為final來達到這個目的。
4)如果一個類成員不是不可變量,那么在成員初始化或者使用get方法獲取該成員變量時,需要通過clone方法來確保類的不可變性。
5)如果有必要,覆蓋Object類的equals()方法和hashCode()方法。在equals()方法中,根據對象的屬性值來比較兩個對象是否相等,并且保證用equals()方法判斷為相等的兩個對象的hashCode()方法的返回值也相等,這可以保證這些對象能正確地放到HashMap或HashSet集合中。
除此之外,還有一些小的注意事項:由于類的不可變性,在創建對象的時候就需要初始化所有的成員變量,因此最好提供一個帶參數的構造方法來初始化這些成員變量。
下面通過給出一個錯誤的實現方法與正確的實現方法來對比說明在實現這種類的時候需要特別注意的問題。首先給出一個錯誤的實現方法如下:


程序的輸出結果為:

需要說明的是,由于Date的對象的狀態是可以被改變的,而ImmutableClass保存了Date類型對象的引用,當被引用對象狀態改變的時候會導致ImmutableClass對象狀態的改變。
其實,正確的實現方法應該如下所示:

程序的輸出結果為:

Java語言里面之所以設計有很多不可變類,主要是因為不可變類具有使用簡單、線程安全、節省內存等優點,但凡事有利就有弊,不可變類自然也不例外,例如,不可變的對象會因為值的不同而產生新的對象,從而導致出現無法預料的問題,所以,切不可濫用這種模式。
- 大話PLC(輕松動漫版)
- 從零開始:數字圖像處理的編程基礎與應用
- Learning RxJava
- Python 3網絡爬蟲實戰
- Java Web程序設計
- Hands-On Natural Language Processing with Python
- 程序設計基礎教程:C語言
- 好好學Java:從零基礎到項目實戰
- C指針原理揭秘:基于底層實現機制
- Hands-On Robotics Programming with C++
- Clojure Polymorphism
- Python Projects for Kids
- Visual C++程序設計與項目實踐
- Python應用與實戰
- Java編程指南:語法基礎、面向對象、函數式編程與項目實戰