BigDecimal - 使用 new 或 valueOf

新手上路,请多包涵

我遇到了两种从双 d 中获取 BigDecimal 对象的方法。

  1. new BigDecimal(d)
  2. BigDecimal.valueOf(d)

哪种方法更好? valueOf 会创建一个新对象吗?

一般来说(不仅仅是 BigDecimal),推荐什么 - new 或 valueOf?

原文由 Manish Mulani 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 846
2 个回答

这是两个独立的问题:“我应该为 BigDecimal 使用什么?”和“我一般会做什么?”

对于 BigDecimal :这有点棘手,因为他们 不做同样的事情BigDecimal.valueOf(double) will use the canonical String representation of the double value passed in to instantiate the BigDecimal object.换句话说: BigDecimal 对象的值将是您在执行 System.out.println(d) 时看到的值。

但是,如果您使用 new BigDecimal(d) ,那么 BigDecimal 将尝试 尽可能准确地 表示 double 值。这 通常会 导致存储的数字比您想要的多得多。严格来说,它比 valueOf() 更正确,但它的直观性要差很多。

JavaDoc 中有一个很好的解释:

此构造函数的结果可能有些不可预测。 One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625 .这是因为 0.1 不能完全表示为 double (或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于 0.1,尽管看起来如此。

一般来说, _如果结果相同_(即在 BigDecimal 的情况下不是,但在大多数其他情况下),那么 valueOf() 应该是首选:它可以缓存常用值(如 Integer.valueOf() 上所见),它甚至可以更改缓存行为,而无需更改调用者。 new始终 实例化一个新值,即使没有必要(最好的例子: new Boolean(true) vs. Boolean.valueOf(true) )。

原文由 Joachim Sauer 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果您使用 BigDecimal 对象来存储货币值,那么我强烈建议您 不要 在其计算中的任何地方涉及任何双精度值。

正如另一个答案中所述,双精度值存在已知的准确性问题,这些问题会再次困扰您。

一旦你克服了这个问题,你的问题的答案就很简单了。始终使用带有字符串值的构造函数方法作为构造函数的参数,因为 --- 没有 valueOf String

如果您想要证明,请尝试以下操作:

 BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);

您将获得以下输出:

 bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01

另请参阅此 相关问题

原文由 DuncanKinnear 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题