java - 当类由可变属性组成时如何确保类的不变性
问题描述
为了使包含可变属性的类不可变,我们应该返回可变属性的防御性副本。考虑下面提到的类
class User {
private String firstName;
private String lastName;
private Date dateOfBirth;
// standard getter and setter for firstName and lastName
public void setdateOfBirth(Date dateOfBirth){}
this.dateOfBirth = new Date(dateOfBirth.getTime());
public Date getDateOfBirth(){
return new Date(dateOfBirth.getTime());
}
}
我们是否可以说,如果使用上述 getter 和 setter 方法设置并返回 date 属性,它将有助于将类创建为不可变的,并有助于为 dateOfBirth 字段保存用户类的内部状态?
解决方案
要在 java 中创建不可变类,您必须执行以下步骤。
1.将类声明为最终类,使其无法扩展。
2.将所有字段设为私有,不允许直接访问。
3.不要为变量提供setter方法
4.将所有可变字段设为final,使其值只能分配一次。
5.通过执行深拷贝的构造函数初始化所有字段。
6.在getter方法中执行对象的克隆以返回一个副本而不是返回实际的对象引用
https://www.journaldev.com/129/how-to-create-immutable-class-in-java
在您的情况下,课程将如下所示
public final class User {
private final String firstName;
private final String lastName;
private final Date dateOfBirth;
public User(String first, String last, Date birth) {
this.firstName = first;
this.lastName = last; //Since String objects are immutable no need to copy
this.dateOfBirth = new Date(birth.getTime()); //Date is mutable so copy parameter to avoid mutation
}
public Date getDateOfBirth(){
return new Date(dateOfBirth.getTime());
}
}
推荐阅读
- c++ - 如何打破 XML 类的 Qt 依赖关系
- python - 情节预测的索引和日期问题
- android - Android 折叠工具栏内容重叠
- php - 用codeigniter 3中的路线翻译网站的正确方法?
- flutter - 如何在下拉按钮中绑定 API 数据并获取选定的值?
- cassandra - Can you scale Cassandra as much as you want?
- python-3.x - 迭代地创建熊猫数据框
- java - 在文件下载完成之前不要关闭浏览器
- xamarin - Playstore 到 Xamarin 表单中的 GetVersionCode
- python - 在不消耗大量内存的情况下将 CSV 转换为 XLS