用Java代表货币价值
我明白BigDecimal是推荐用Java表示货币价值的最佳实践。 你用什么? 有更好的图书馆,而不是你喜欢使用?
BigDecimal
一路。 我听说有些人创build了自己的Cash
或Money
类,用货币来封装现金价值,但在皮下,它仍然是一个BigDecimal
,可能是BigDecimal.ROUND_HALF_EVEN
四舍五入。
编辑:正如唐在他的回答中提到的,有timeandmoney这样的开源项目,虽然我鼓励他们试图阻止开发人员重新发明轮子,我只是没有足够的信心使用前alpha版库它在生产环境中。 另外,如果你在引擎盖下挖掘,你会看到他们也使用BigDecimal
。
对于通过search引擎到达这里的人来说,了解JodaMoney可能是有用的: http : //www.joda.org/joda-money/ 。
我不是在这里expression自己的看法,但是对于BigDecimal来说,有很多人可能会抛出异议:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
我之前遇到的一个便利的图书馆是Joda-Money图书馆。 它的一个实现确实基于BigDecimal。 它基于ISO-4217货币规范,可以支持定制的货币列表(通过CVS加载)。
这个库有less量的文件,如果需要修改,可以快速通过。 Joda-Money是在Apache 2.0许可下发布的。
如果你只是使用美元和美分,我会使用一个很长的(抵消2个小数位)。 如果你需要更多的细节,大的小数可能是要走的路。
无论哪种方式,我可能会扩展类有一个.toString()使用正确的格式,并作为一个地方把其他方法可能出现(长期来说,乘法和分裂将会出错,如果小数点是没有调整)
另外,如果你使用定义自己的类和接口,那么你可以随意replace实现。
BigDecimal
或另一个固定点表示是通常需要的金钱。
浮点( Double
, Float
)表示和计算是不精确的,导致错误的结果。
处理时间和金钱时必须小心谨慎。
当你用金钱工作的时候,我希望每个人都应该知道永远不要使用浮动或双重。
但是我不确定BigDecimal。
在大多数情况下,如果你只保持一个int或long的分数,那么你会好起来的。 这样你从不处理小数位。
打印时只显示美元。 总是与美分内部使用整数工作。 如果需要划分或需要使用Math.abs(),这可能是棘手的。
但是,你可能会关心半分,甚至百分之一分。 我不知道这是做什么的好方法。 你可能只需要处理千分之一美分,并使用很长时间。 或者,也许你会被迫使用BigDecimal
我会在这方面做更多的阅读,但是不要忽视所有开始谈论使用浮动或双倍来代表金钱的人。 他们只是在问问题。
我觉得我的build议并不完整,所以请多加注意。 你正在处理危险的types!
创build一个Money类是要走的路。 在下面使用BigDecimal(甚至是int)。 然后使用货币类来定义舍入约定。
不幸的是,没有运算符重载Java使得创build这样的基本types非常不愉快。
有一个更好的图书馆,时间和金钱 。 海事组织,它远远优于由JDK提供的代表这两个概念的库。
绝对不是BigDecimal。 有很多特殊的四舍五入和expression规则,你必须担心。
Martin Fowlerbuild议实施专门的Money类别来表示货币金额,并且还实施货币转换规则。
嘿,这里是关于BigDecimal的一篇非常有趣的文章,以及为什么有时使用它而不是双打的例子。 BigDecimal教程 。
最终显示货币值时,可以使用DecimalFormat类。 它提供了本地化的支持,并且是非常可扩展的。
我将BigDecimal封装在Money类中,该类也具有上面提到的货币。 重要的是你做了一个极端的unit testing,特别是如果使用不同的货币。 如果你添加一个方便的构造函数来获取一个string或者一个工厂方法,这样你就可以像这样编写你的testing:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
总是有限制和具体涉及。 任何人如果没有足够的经验去理解下一篇文章中提到的微妙问题,在处理现实世界的财务数据之前,应该认真地重新考虑:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal不是唯一正确的表示或拼图的唯一部分。 在某些条件下,使用存储为整数的Money类支持的Money类可能就足够了,并且会比BigDecimal快得多。 是的,这意味着使用美元作为货币和限额,但是这样的限制对于许多用例来说是完全可以接受的,而且所有货币都有特殊的四舍五入和小分类的情况,所以没有“通用”的解决scheme。