如何使 class 不可变且其中包含 Date 对象?

How to make a class immutable with Date object in it?

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

但我最近遇到一个问题,面试官要求候选人创建一个不可变的 class,其中包含 java.util.Date。我的第一印象告诉我这是不可能的,尽管我们可以使用包含日期字符串而不是 Date 对象本身的 String 来解决问题。

请澄清一下。谢谢。

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

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

  1. 您需要确保 class 不能被覆盖,- 使其成为最终的。

  2. 将所有字段设为私有和最终字段。

  3. 不要提供任何设置器或任何更改实例变量的方法。

  4. 防御性地复制被调用者和调用者之间的对象。

    考虑 this tutorial 更多

要使 class 不可变,最简单的做法是创建 Date 对象的防御性副本(当它在构造参数中传递时)。然后也不要提供任何设置器。像这样,class 中的日期字段的引用对于此 class 之外的代码是可见的,因此无法修改日期。

查看 Tom 的评论以了解所需的 getter 特征!感谢补充。

(Getter 也应该 return 日期字段的副本,因为日期本身是可变的,并且从 getter 更改 returned 字段将也更改 class 的字段。)

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

1) 不要提供“setter”方法。

2) 将所有字段设为最终字段和私有字段

3) 不允许 subclasses 覆盖方法 - 将 class 声明为 final

4) 对于可变实例变量 - Ex date: 在这种情况下要特别注意。

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 是在私有构造函数中设置的字段