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”。