不可变对象(Immutable Object)是指一旦创建后,其状态(即对象的数据)不能被修改或改变的对象。在 Java 中,创建不可变对象有几个关键点和方法。
特征和优势:
-
不可变性: 对象的状态在创建后不能被修改,所有字段都是 final 的,没有提供修改状态的方法(setter)。
-
线程安全: 不可变对象天生具有线程安全性,因为它的状态不会被修改,不需要额外的同步措施。
-
缓存友好: 因为不可变对象的状态不会变化,可以安全地缓存其实例,提高性能。
创建不可变对象的方法:
在 Java 中创建不可变对象通常需要遵循以下几个步骤:
-
使用 final 修饰类: 不可变对象通常应该是 final 类,防止子类改变其行为。
-
所有字段私有化并用 final 修饰: 所有字段都应该是私有的,并使用 final 关键字修饰,确保它们只能在对象构造时被初始化一次。
-
不提供修改状态的方法(setter): 不可变对象不应该提供任何修改其状态的公共方法,如不提供设置字段值的方法。
-
确保可变字段的安全性: 如果对象包含可变对象(如集合),确保在返回它们时进行防御性复制(defensive copy),以防止外部修改原始集合。
下面是一个示例,展示如何创建一个简单的不可变对象:
public final class ImmutableObject {
private final int value;
private final String name;
private final List<String> list; // 可变对象需要进行防御性复制
public ImmutableObject(int value, String name, List<String> list) {
this.value = value;
this.name = name;
this.list = new ArrayList<>(list); // 进行防御性复制
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
public List<String> getList() {
return new ArrayList<>(list); // 返回防御性复制后的列表
}
}
- 说明:
ImmutableObject
类被声明为final
,不能被子类化。value
和name
字段被声明为final
,一旦在构造函数中初始化后,它们的值就不能再被修改。list
字段是一个可变对象,为了保持不可变性,构造函数中进行了防御性复制,返回该字段时也需要进行防御性复制。
这样的设计确保了 ImmutableObject
类的实例在创建后其状态不可改变,从而实现了不可变对象的特性。