當我們在Java中創建不可變對象時,我們需要確保對象的狀態在創建之后不能被修改。以下是一些具體的實現細節和例子,展示了如何在Java中創建不可變對象。
實現細節
- 使用
final
關鍵字:- 類定義前使用
final
關鍵字,表示該類不能被繼承,從而防止子類覆蓋其方法或添加新的狀態。 - 字段前使用
final
關鍵字,表示該字段的值在初始化之后不能被修改。
- 類定義前使用
- 不提供修改器方法:
- 不提供任何
setter
方法,確保外部類不能通過公共接口修改對象的狀態。
- 不提供任何
- 構造函數中初始化所有字段:
- 在構造函數中初始化所有
final
字段,并確保一旦初始化,它們就不會被再次賦值。
- 在構造函數中初始化所有
- 確保引用的對象也是不可變的:
- 如果字段是引用類型,則需要確保引用的對象本身也是不可變的,或者字段引用的是不可變的集合(如
Collections.unmodifiableList
)。
- 如果字段是引用類型,則需要確保引用的對象本身也是不可變的,或者字段引用的是不可變的集合(如
- 返回不可變集合的視圖:
- 如果類包含集合類型的字段,并且需要對外提供訪問接口,可以返回該集合的不可變視圖,以防止外部類修改集合內容。
例子
簡單的不可變類
java復制代碼
public final class ImmutablePerson { | |
private final String name; | |
private final int age; | |
public ImmutablePerson(String name, int age) { | |
this.name = name; | |
this.age = age; | |
} | |
public String getName() { | |
return name; | |
} | |
public int getAge() { | |
return age; | |
} | |
// 其他方法(如果有的話)... | |
@Override | |
public String toString() { | |
return "ImmutablePerson{" + | |
"name='" + name + '\'' + | |
", age=" + age + | |
'}'; | |
} | |
} |
引用不可變對象的類
java復制代碼
public final class ImmutableAddress { | |
private final String street; | |
private final String city; | |
private final String country; | |
public ImmutableAddress(String street, String city, String country) { | |
this.street = street; | |
this.city = city; | |
this.country = country; | |
} | |
// Getter方法... | |
@Override | |
public String toString() { | |
return "ImmutableAddress{" + | |
"street='" + street + '\'' + | |
", city='" + city + '\'' + | |
", country='" + country + '\'' + | |
'}'; | |
} | |
} | |
// 使用ImmutableAddress的ImmutablePerson | |
public final class ImmutablePersonWithAddress { | |
private final String name; | |
private final int age; | |
private final ImmutableAddress address; | |
public ImmutablePersonWithAddress(String name, int age, ImmutableAddress address) { | |
this.name = name; | |
this.age = age; | |
this.address = address; // 引用不可變對象 | |
} | |
// Getter方法... | |
@Override | |
public String toString() { | |
return "ImmutablePersonWithAddress{" + | |
"name='" + name + '\'' + | |
", age=" + age + | |
", address=" + address + | |
'}'; | |
} | |
} |
返回不可變集合視圖的例子
java復制代碼
public final class ImmutableContainer { | |
private final List<String> items = new ArrayList<>(); | |
public ImmutableContainer(List<String> initialItems) { | |
// 假設initialItems是安全的,并且我們想要創建一個不可變的副本 | |
this.items.addAll(initialItems); | |
} | |
public List<String> getItems() { | |
// 返回不可變的列表視圖 | |
return Collections.unmodifiableList(items); | |
} | |
// 其他方法... | |
} |
在上面的例子中,ImmutableContainer
類包含了一個列表字段items
,但在getItems
方法中,它返回了一個不可變的列表視圖,從而防止了外部類修改該列表的內容。