最佳做法是不公开Object(Entity)的内部引用.因此,如果一个Object有一个类型的字段,java.util.Date那么例如该字段的getter应该不返回原始日期而是它的副本.
但是对于java.util.Date,有两种常见的方法来创建该副本:
(Date) originalDate.clone()new Date(originalDate.getTime()) 我的问题是,哪种方式更好,为什么?
Ami*_*ani 35
阅读有效的Java.创建副本的首选方法是使用复制构造方法.
Bill Venners:在你的书中,你建议使用复制构造函数,而不是实现Cloneable和编写克隆.你能详细说明吗?
Josh Bloch:如果你已经阅读了我的书中关于克隆的项目,特别是如果你在阅读之间阅读,你就会知道我认为克隆已经深受打击.存在一些设计缺陷,其中最大的一个是Cloneable接口没有克隆方法.这意味着它根本不起作用:制作一些Cloneable并没有说明你可以用它做什么.相反,它说明了内部可以做些什么.它说如果通过反复调用super.clone它最终调用Object的clone方法,这个方法将返回原始的字段副本.
rob*_*pvn 15
如果你在防御性编码,你会想要复制构造函数.请参阅Effective Java的这篇文章:
另请注意,我们没有使用Date的克隆方法来制作防御性副本.因为Date是非最终的,所以不能保证clone方法返回一个类为java.util.Date的对象; 它可以返回一个专门为恶意恶作剧设计的不受信任的子类的实例.例如,这样的子类可以在创建私有静态列表时记录对每个实例的引用,并允许攻击者访问该列表.这将使攻击者在所有实例中自由统治.要防止此类攻击,请不要使用clone方法制作类型可由不信任方进行子类化的参数的防御副本.