当我们在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
方法中,它返回了一个不可变的列表视图,从而防止了外部类修改该列表的内容。