据我所知,BigDecimal是用于在Java中表示货币值的推荐最佳实践。你用什么?您是否更喜欢使用更好的库?
答案 0 :(得分:76)
BigDecimal
一路走来。我听说有些人创建自己的Cash
或Money
类,用货币封装现金值,但在皮肤下它仍然是BigDecimal
,可能是{{3}四舍五入。
编辑:正如Don在BigDecimal.ROUND_HALF_EVEN
中提到的那样,有像his answer这样的开源项目,虽然我鼓励他们试图阻止开发人员重新发明轮子,我对pre-alpha库没有足够的信心在生产环境中使用它。此外,如果你在引擎盖下挖掘,你会看到timeandmoney。
答案 1 :(得分:50)
通过搜索引擎到达这里的人可以了解JodaMoney:http://www.joda.org/joda-money/。
答案 2 :(得分:13)
我不是在这里表达我的意见,但是有一些很好的论据反对BigDecimal有人应该抛弃:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
答案 3 :(得分:8)
我之前遇到的一个方便的库是Joda-Money库。它的一个实现确实基于BigDecimal。它基于货币的ISO-4217规范,可以支持自定义货币列表(通过CVS加载)。
此库包含少量文件,如果需要修改,可以快速浏览。 Joda-Money是在Apache 2.0许可下发布的。
答案 4 :(得分:7)
如果你只是使用美元和美分,我会使用一个长(偏移2位小数)。如果您需要更多细节,可以选择大小数。
无论哪种方式,我可能会扩展类以使用正确格式的.toString(),并作为放置其他可能出现的方法的地方(如果长,乘法和除法将会出错,如果小数未调整)
此外,如果您使用定义自己的类和接口,那么您可以随意替换实现。
答案 5 :(得分:3)
BigDecimal
或其他固定点表示是通常需要的钱。
浮点(Double
,Float
)表示和计算不准确,导致错误结果。
答案 6 :(得分:2)
在处理时间和金钱时,你必须非常小心。
当你在处理钱财时,我希望每个人都应该知道永远不要使用浮子或双人。
但我不确定BigDecimal。
在大多数情况下,如果您只是跟踪int或long中的美分,那么您将没事。这样你就不会处理小数位。
您只能在打印时显示美元。始终使用整数使用内部美分。如果需要划分或需要使用Math.abs(),这可能会很棘手。
然而,你可能会关心半分钱,甚至百分之一百分钱。我不知道这样做有什么好办法。你可能只需要处理千分之一美分并使用很长时间。或者你可能会被迫使用BigDecimal
我会在这方面做更多的阅读,但忽略所有开始谈论使用浮点数或双倍代表金钱的人。他们只是在寻找麻烦。
我觉得我的建议并不完整,所以请加入更多。你正在处理危险的类型!
答案 7 :(得分:2)
创建Money类是可行的方法。在下面使用BigDecimal(甚至是int)。然后使用Currency类来定义舍入约定。
不幸的是,没有运算符重载Java会让创建这样的基本类型变得非常不愉快。
答案 8 :(得分:2)
有一个更好的图书馆timeandmoney。 IMO,它远远优于JDK提供的用于表示这两个概念的库。
答案 9 :(得分:1)
绝对不是BigDecimal。你需要担心的有很多特殊的舍入和演示规则。
Martin Fowler建议实施专用的Money类来表示货币金额,并且还实施货币转换规则。
答案 10 :(得分:1)
嘿,这是关于BigDecimal的一篇非常有趣的文章,以及为什么有时使用它而不是双打的一个说明性示例。 BigDecimal Tutorial
答案 11 :(得分:0)
最终显示货币值时,您可以使用DecimalFormat类。它提供本地化支持,并且具有很强的可扩展性。
答案 12 :(得分:0)
我会将BigDecimal封装在Money类中,该类也具有与上面提到的货币一样的货币。重要的是你进行了大量的单元测试,特别是如果使用不同的货币。另外,如果你添加一个方便的构造函数来获取相同的字符串或工厂方法,这样你就可以编写类似这样的测试:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
答案 13 :(得分:0)
总是存在约束和细节。任何没有足够经验去理解下一篇文章中提出的微妙问题的人都应该在处理现实世界的财务数据之前认真重新考虑:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal不是唯一正确的表示或唯一的拼图。在某些条件下,使用以美分为单位的Money类存储为整数可能就足够了,并且比BigDecimal快得多。是的,这意味着使用美元作为货币和限制金额,但这种限制对于许多用例是完全可以接受的,并且所有货币都有特殊情况用于舍入和子面额,所以没有“通用”解决方案。