java.util.日期克隆或复制以不公开内部引用
最佳做法是不公开对象(实体)的内部引用。因此,如果一个对象具有 java.util.Date
类型的字段,那么例如,此字段的 getter 应该返回的不是原始日期,而是它的副本。
但是对于java.util.Date,有两种常见的方法来创建该副本:
- 克隆:
(Date) originalDate.clone()
- 通过构造函数复制
new Date(originalDate.getTime())
我的问题是,哪种方式更好,为什么?
最佳做法是不公开对象(实体)的内部引用。因此,如果一个对象具有 java.util.Date
类型的字段,那么例如,此字段的 getter 应该返回的不是原始日期,而是它的副本。
但是对于java.util.Date,有两种常见的方法来创建该副本:
(Date) originalDate.clone()
new Date(originalDate.getTime())
我的问题是,哪种方式更好,为什么?
如果它肯定只是一个,那么无论哪种方式都不会有任何区别。Date
如果实际的对象可能是(例如)的子类,那么我希望这将保留额外的信息(包括它是哪个类),而调用构造函数则不会。Date
java.sql.Date
clone()
顺便说一句,如果你使用Joda Time,你就不会有这个问题,因为有很多不可变的类型可以使用。这也是一个更好的API:)
阅读有效的 Java。创建副本的首选方法是使用复制构造函数方法。
Bill Venners:在你的书中,你建议使用复制构造函数,而不是实现 Cloneable 和编写 clone。您能详细说说吗?
Josh Bloch:如果你读过我书中关于克隆的文章,特别是如果你在字里行间阅读,你就会知道我认为克隆已经严重断裂了。存在一些设计缺陷,其中最大的缺陷是可克隆接口没有克隆方法。这意味着它根本行不通:制作可克隆的东西并不能说明你可以用它做什么。相反,它说的是它可以在内部做些什么。它说,如果通过重复调用super.clone,它最终调用Object的克隆方法,则此方法将返回原始方法的字段副本。