这只是从学术学习的角度来看。我所知道的是,每当我们想让一些类不可变时, - 它必须由最终的原始字段组成 - 在构造对象期间,引用不会逃脱 - 如果使用其他对象,那么这些对象也需要递归不可变或者像API.lang.String这样的API不可变类,以及其他一些详细的了望点!
但最近我遇到了一个问题,其中一位采访者要求候选人创建一个包含java.util.Date的不可变类。我的第一印象是尽管我们可以使用包含日期字符串的字符串而不是Date对象本身的变通办法来解决它。
请在此澄清我。谢谢。
答案 0 :(得分:17)
这里使类不可变的最简单的方法是创建Date对象的防御副本(当它在构造参数中传递时)。那么也不要提供任何setter。像这样,在类之外的代码中不能引用类中的Date字段,因此无法修改Date。
请参阅Tom对所需吸气剂特性的评论!谢谢你的补充。
(Getter也应该返回日期字段的副本,因为Date本身是可变的,并且从getter更改返回的字段也会改变类的字段。)
有关更多信息和详细信息: http://www.informit.com/articles/article.aspx?p=31551&seqNum=2
答案 1 :(得分:5)
我建议围绕您使用的日期创建一个包装类,并且不提供任何可以实际更改该值的setter或任何方法。
为了使它不可变,你需要考虑以下事项:
在被叫方和来电者之间防御性地复制对象。
考虑this tutorial了解更多
答案 2 :(得分:0)
1)不要提供“setter”方法。
2)将所有字段设为最终和私有
3)不允许子类重写方法 - 将类声明为final
4)对于可变实例变量 - 出现日期:在这种情况下要特别注意。
5)使构造函数成为私有的,并在工厂方法中构造实例。 将对象创建逻辑存储在单个位置的工厂方法。
public static MyImmutableClass createNewInstance(Integer fld1, String fld2, Date date)
{
return new MyImmutableClass (fld1, fld2, date);
}
6)应该返回一个复制了内容的新Date对象。
public Date getDateField() {
return new Date(dateField.getTime());
}
- 这里dateField是在私有构造函数
中设置的字段