不可变类的配方
不可变对象是无法更改其状态的对象。不可变类是一个类,其实例在设计和实现方面是不可变的。最常见的不可变性示例 Java 类是 java.lang.String 。
以下是一个陈规定型的例子:
public final class Person {
private final String name;
private final String ssn; // (SSN == social security number)
public Person(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
public String getName() {
return name;
}
public String getSSN() {
return ssn;
}
}
对此的一种变化是将构造函数声明为 private
并提供 public static
工厂方法。
不可变类的标准配方如下:
- 必须在构造函数或工厂方法中设置所有属性。
- 应该没有制定者。
- 如果出于接口兼容性原因需要包含 setter,它们应该不执行任何操作或抛出异常。
- 所有属性都应声明为
private
和final
。 - 对于引用可变类型的所有属性:
- 应该使用通过构造函数传递的值的深层副本初始化该属性,并且
- 属性的 getter 应该返回属性值的深层副本。
- 该类应声明为
final
,以防止有人创建不可变类的可变子类。
还有几点需要注意:
- 不可变性不会阻止对象可以为空; 例如,
null
可以分配给String
变量。 - 如果将不可变类属性声明为
final
,则实例本身就是线程安全的。这使得不可变类成为实现多线程应用程序的良好构建块。