我最近在一个项目中开始使用 Sonar,我得到了一条关于使用构造函数的 PMD 规则new BigDecimal(double val)
。当我阅读 java 文档时,我发现 new BigDecimal(double val) 有点不可预测,我应该使用new BigDecimal(String val)
可预测的。
这是 javadoc 所说的BigDecimal
public BigDecimal(double val)
:
将 double 转换为 BigDecimal,BigDecimal 是 double 的二进制浮点值的精确十进制表示。返回的 BigDecimal 的小数位数是使 (10scale × val) 为整数的最小值。
笔记:
此构造函数的结果可能有些不可预测。有人可能会假设
new BigDecimal(0.1)
用 Java 编写的 aBigDecimal
正好等于 0.1(未缩放的值 1,比例为 1),但它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 不能完全表示为双精度数(或者,就此而言,不能表示为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于 0.1,尽管看起来如此。另一方面,String 构造函数是完全可预测的:编写
new BigDecimal("0.1")
创建的 aBigDecimal
正好等于 0.1,正如人们所期望的那样。因此,一般建议优先使用 String 构造函数。当必须将 double 用作 a 的源时
BigDecimal
,请注意此构造函数提供了精确转换;它与使用Double.toString(double)
方法将双精度转换为字符串然后使用BigDecimal(String)
构造函数给出的结果不同。要获得该结果,请使用静态valueOf(double)
方法。
为什么这个构造函数真的存在?这还new BigDecimal(String val)
不够吗?我什么时候应该使用new BigDecimal(double val)
构造函数?