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】:

等一下...通过在getSomeDatesetSomeDate 方法中复制对象,我们并没有消除安全风险,因为更改的对象通过setSomeDate 返回并且副本保留更改的值。为了解决这种安全问题,有必要删除setSomeDate,或者根本不用担心。

【讨论】:

通过返回对象的副本,我们避免了内部表示被共享 - 这将有助于避免调用代码(即使它接收到本地变量的这个属性)操纵这个,bean属性会改变。很明显,setsomeDate 不能被删除,因为这是基本的 bean 行为。【参考方案4】:

根据您的用例,您可以返回 someDate.getTime() 而无需将其包装在 Date 中。

【讨论】:

以上是关于Findbugs 与 Java 中 Date 对象的可变性有关的问题的主要内容,如果未能解决你的问题,请参考以下文章

eclipse的findbugs插件安装无效问题

Java中Date对象与String互转

FindBugs : EI_EXPOSE_REP 背后的真正威胁

Java代码Bug分析插件 FindBugs

Java 资源管理:了解 Findbugs 结果

Java基础(37):Java中日期的显示与格式定值----Date与SimpleDateFormat的试用