如何使用Date对象使一个类不可变?

时间:2015-02-09 08:34:50

标签: java date immutability

这只是从学术学习的角度来看。我所知道的是,每当我们想让一些类不可变时, - 它必须由最终的原始字段组成 - 在构造对象期间,引用不会逃脱 - 如果使用其他对象,那么这些对象也需要递归不可变或者像API.lang.String这样的API不可变类,以及其他一些详细的了望点!

但最近我遇到了一个问题,其中一位采访者要求候选人创建一个包含java.util.Date的不可变类。我的第一印象是尽管我们可以使用包含日期字符串的字符串而不是Date对象本身的变通办法来解决它。

请在此澄清我。谢谢。

3 个答案:

答案 0 :(得分:17)

这里使类不可变的最简单的方法是创建Date对象的防御副本(当它在构造参数中传递时)。那么也不要提供任何setter。像这样,在类之外的代码中不能引用类中的Date字段,因此无法修改Date。

请参阅Tom对所需吸气剂特性的评论!谢谢你的补充。

(Getter也应该返回日期字段的副本,因为Date本身是可变的,并且从getter更改返回的字段也会改变类的字段。)

有关更多信息和详细信息: http://www.informit.com/articles/article.aspx?p=31551&seqNum=2

答案 1 :(得分:5)

我建议围绕您使用的日期创建一个包装类,并且不提供任何可以实际更改该值的setter或任何方法。

为了使它不可变,你需要考虑以下事项:

  1. 您需要确保无法覆盖该类, - 将其作为最终版本。
  2. 将所有字段设为私有和最终字段。
  3. 不要提供任何更改实例变量的setter或任何方法。
  4. 在被叫方和来电者之间防御性地复制对象。

    考虑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是在私有构造函数

中设置的字段