Findbugs 与 Java 中 Date 对象的可变性有关的问题
Posted
技术标签:
【中文标题】Findbugs 与 Java 中 Date 对象的可变性有关的问题【英文标题】:Findbugs issues with mutability of Date object in Java 【发布时间】:2011-12-17 11:08:22 【问题描述】:这更像是对1 和2 问题的跟进。
如问题中所述,以下代码
public Date getSomeDate()
return someDate;
会给你 findbug 错误issue。
建议的解决方案是在 getter 和 setter 中复制 Date 对象,例如
public Date getSomeDate()
return new Date(someDate.getTime());
这是一种好方法还是有其他替代方法?
在 java 中是否有任何可用的不可变日期库可以解决这个问题?
【问题讨论】:
你的意思是不可变的吧?无论如何,所述方法是完美的。 @PrinceJohnWesley:谢谢,是的。我已经更新了Qs。你的意思是说可以在所有的getter和setter中使用Date构造函数? 只要您不将调用暴露给外部库。您不需要深度克隆(构造函数)它,因为您知道自己在做什么。否则,如果它是可变的,则始终给出差异参考。试试 joda time api 【参考方案1】:大家注意...
除了调整 getter 和 setter 之外,您还需要注意 null 值:
public Date getSomeDate()
if (this.someDate == null)
return null;
return new Date(this.someDate.getTime());
public void setSomeDate(final Date someDate)
if (someDate == null)
this.someDate = null;
else
this.someDate = new Date(someDate.getTime());
【讨论】:
我希望不会。我希望你知道someDate
不是 null 并且将 null 传递给 setter 被认为是错误的事实。防御性复制甚至免费为我们提供了 null 检查。【参考方案2】:
JodaTime 具有不可变的日期。
当然,可以在 getter 中使用 Date
构造函数,为什么不呢?
也就是说,仅仅因为 FindBugs 将可变状态视为潜在错误,并不意味着它本质上值得关注——这取决于类的使用方式。不变性消除了一种类型的错误,您可能需要也可能不需要非常关心。
【讨论】:
你能举个例子说明它消除了什么样的错误吗? @TomDane ... 那种使你的状态从你下面变异出来的东西。这不是Date
独有的,它与 anything 相同,可让您改变内部状态。【参考方案3】:
等一下...通过在getSomeDate
和setSomeDate
方法中复制对象,我们并没有消除安全风险,因为更改的对象通过setSomeDate
返回并且副本保留更改的值。为了解决这种安全问题,有必要删除setSomeDate
,或者根本不用担心。
【讨论】:
通过返回对象的副本,我们避免了内部表示被共享 - 这将有助于避免调用代码(即使它接收到本地变量的这个属性)操纵这个,bean属性会改变。很明显,setsomeDate 不能被删除,因为这是基本的 bean 行为。【参考方案4】:根据您的用例,您可以返回 someDate.getTime()
而无需将其包装在 Date
中。
【讨论】:
以上是关于Findbugs 与 Java 中 Date 对象的可变性有关的问题的主要内容,如果未能解决你的问题,请参考以下文章