JSR 354为Java引入金钱与货币的完美支持

一、基于ISO-4217实现的货币处理类的问题

 java1.4引入基于ISO-4217的java.util.Currency类以及将数字转换为货币金额格式的类java.text.DecimalFormat,转换后的值用于基本的数学计算后也能正确的以货币形式呈现。但是如果仔细研究便会发现很多需求并没有被满足,只是部分实现而已。

  • java.util.Currency类缺少了几种很重要的ISO货币代码。比如缺少了瑞士的两种瑞士法郎代码CHE和CHW,离线人民币CNH。(与之相反,各种美元代码如USD、USS、USN则全部都有)
  • Java1.7发布之后,可以添加自定义的货币,但需要开发者编写并注册一个所谓的“Java扩展”(一种Java机制,安装在JRElib文件夹下),这对很多公司来说并不可行。而且当前的Currency类不能处理在JavaEE环境或者多租户环境的情况下动态变化的需求。对其它使用场景例如虚拟货币则几乎完全不支持。
  • java.text.DecimalFormat类提供了很多基本货币格式转换的功能,但仍然缺乏健壮的格式化能力;其次,所有的国际货币都使用标准的每隔3位数字就用逗号分隔的表示方法,我们无法用当前的工具灵活定义其它的分隔方式,比如印度卢比除了最后一组是3位数字之外,其它都是2位数字一组(例如INR 12,23,123.34);最后,这种货币格式化也是线程不安全的。


二、引入JSR354

JSR354引用

地址:http://repo1.maven.org/maven2/javax/money/money-api/1.0.3/

<dependency>
      <groupId>org.javamoney</groupId>
      <artifactId>moneta</artifactId>
      <version>1.0.3</version>
</dependency>

JSR354的设计目标:

  • 1.提供处理和计算货币金额的API
  • 2.定义货币和货币金额的类别,以及货币四舍五入
  • 3.处理汇率
  • 4.处理货币和货币金额的格式化和解析

JSR354包结构介绍

  • javax.money.*  : 币种,金额基本服务和操作
  • javax.money.convert.* :货币汇兑转换
  • javax.money.format.* :货币格式化操作
  • javax.money.spi.*  : 启动配置服务

JSR354主要接口设计




三、JSR354 API描述

CurrencyUnit

CurrencyUnit模拟货币的最小属性。它的实例可以使用Monetary.getCurrency方法获得,我们使用货币的字符串表示形式创建CurrencyUnit,这可能会导致我们尝试使用不存在的代码创建货币的情况。使用不存在的代码创建货币会引发UnknownCurrency异常。


MonetaryAmount

MonetaryAmount是货币金额的数字表示。它始终与CurrencyUnit关联,并定义货币的货币表示形式。金额可以用不同的方式来实现,重点放在由每个具体用例所定义的货币表示要求的行为上。例如。Money和FastMoney是MonetaryAmount接口的实现。Money使用BigDecimal类型存储金额,精度高,可以用于财务会计等专业领域;FastMoney使用long类型存储金额,根据英文文档描述,要比Money快10-15倍;但是精度缺受限于long类型。


需要注意:

  • 当且仅当实现类,货币单位,以及数值全部相等时,才认为Money和FastMoney相同。

MonetaryAmount运算操作




MonetaryAmount集合的过滤,排序,分组操作。



自定义的MonetaryAmount操作 

MonetaryOperator是一个函数式接口,通过实现这个接口,可以实现自定义的操作MonetaryAmount,它接收一个MonetaryAmount入参并返回一个新的MonetaryAmount对象。



MonetaryAmountFormat解析字符串和格式化

MonetaryAmount可以通过JAVA自带的MonetaryAmountFormat来与字符串进行解析/格式化。 也可以通过自定义的AmountFormatQueryBuilder对其进行格式化



汇率和汇兑

货币兑换率可以通过ExchangeRateProvider来获取。JavaMoney自带了多个不同的ExchangeRateProvider的实现。其中最重要的两个是ECBCurrentRateProvider与 IMFRateProvider。

ECBCurrentRateProvider查询的是欧洲中央银行(European Central Bank,ECB)的数据而IMFRateProvider查询的是国际货币基金组织(International Monetary Fund,IMF)的汇率。如果没有指定ExchangeRateProvider的话返回的就是CompoundRateProvider。CompoundRateProvider会将汇率转换请求委派给一个ExchangeRateProvider链并将第一个返回准确结果的提供商的数据返回。


汇兑时通过ExchangeRateProvider返回的属性CurrencyConversions进行汇兑操作的。



猜你喜欢

转载自blog.csdn.net/piqianming/article/details/79964118
今日推荐