BigDecimal - 使用new或valueOf

时间:2011-08-25 06:54:19

标签: java bigdecimal

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

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

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

一般情况下(不仅仅是BigDecimal),推荐什么 - new或valueOf?

感谢。

3 个答案:

答案 0 :(得分:141)

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

对于BigDecimal:这有点棘手,因为他们不做同样的事情BigDecimal.valueOf(double)将使用传入的doublecanonical String representation来实例化BigDecimal对象。换句话说:BigDecimal对象的值将是您在System.out.println(d)时看到的内容。

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

在JavaDoc中有一个很好的解释:

  

这个构造函数的结果可能有些不可预测。有人可能会认为在Java中编写new BigDecimal(0.1)会创建一个BigDecimal,它恰好等于0.1(未缩放值为1,标度为1),但它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能精确地表示为double(或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管有外观。

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

答案 1 :(得分:40)

如果您使用BigDecimal个对象来存储货币值,那么我强烈建议您在计算的任何位置执行 NOT 任何双值。

正如另一个答案中所述,双重值存在已知的准确性问题,这些问题会让您大失所望。

一旦过了那个问题,你问题的答案很简单。始终使用带有String值的构造函数方法作为构造函数的参数,因为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

另见related question

答案 2 :(得分:4)

基本上valueOf(double val)只是这样做:

return new BigDecimal(Double.toString(val));

因此 - >是的,将创建一个新对象:)。

总的来说,我认为这取决于你的编码风格。如果两者都是相同的结果,我不会混合valueOf和“new”。