BigDecimal – 使用new或valueOf

我遇到了两种方法让BigDecimal对象脱离双d。

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

这将是一个更好的方法? 会valueOf创build一个新的对象?

一般来说(不只是BigDecimal),推荐什么 – 新的或valueOf?

谢谢。

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

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

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

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

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

一般来说, 如果结果是相同的 (即不是BigDecimal ,但在大多数情况下),那么valueOf()应该是首选的:它可以caching通用值(如在Integer.valueOf()所见)它甚至可以改变caching行为,而不需要改变主叫方。 new总是实例化一个新的值,即使不是必要的(最好的例子: new Boolean(true) vs. Boolean.valueOf(true) )。

如果您正在使用BigDecimal对象来存储货币值,那么我强烈build议您不要在计算中的任何位置包含任何双值。

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

一旦你过去了,你的问题的答案很简单。 始终使用带有String值的构造方法作为构造方法的参数,因为String没有valueOf方法。

如果您需要certificate,请尝试以下操作:

 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 

另请参阅这个相关的问题

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

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

所以 – >是的,一个新的对象将被创build:)。

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