我遇到了两种将BigDecimal对象从双d中取出的方法。
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
哪种方法更好? valueOf会创建一个新对象吗?
一般情况下(不仅仅是BigDecimal),推荐什么 - new或valueOf?
感谢。
答案 0 :(得分:141)
这是两个不同的问题:“我应该为BigDecimal
使用什么?”和“我一般做什么?”
对于BigDecimal
:这有点棘手,因为他们不做同样的事情。 BigDecimal.valueOf(double)
将使用传入的double
值canonical 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
答案 2 :(得分:4)
基本上valueOf(double val)只是这样做:
return new BigDecimal(Double.toString(val));
因此 - >是的,将创建一个新对象:)。
总的来说,我认为这取决于你的编码风格。如果两者都是相同的结果,我不会混合valueOf和“new”。