Java货币显示名称国际化

时间:2017-10-31 10:31:20

标签: java internationalization currency

为什么某些显示名称以英语显示,尽管语言环境不是英语(即:未翻译)。

例如: 地区:" ru"没有翻译

Locale locale = new Locale("ru");
Currency curr = Currency.getInstance("USD");
System.out.println(curr.getDisplayName(locale));
// US Dollar

区域设置:" es"已翻译

Locale locale = new Locale("es");
Currency curr = Currency.getInstance("USD");
System.out.println(curr.getDisplayName(locale));
// dólar estadounidense
这是故意的吗? 或者Java没有得到翻译它? 或者我做错了什么?

我试图找到存储这些翻译但无法找到它们的文件。如果有人能指出我那个有用的资源。

感谢。

1 个答案:

答案 0 :(得分:13)

区域设置服务提供商

  

Java使用可扩展的机制来提供数据(例如字符串,   格式化程序等)本地化。

     

类可以实现LocaleServiceProvider成为工厂   本地敏感数据。 java.utiljava.text中的很多课程   依靠这些提供商与不同的Locale合作   委托创建对象。

您可以在java.util.spi包中找到本地服务提供商的示例,这些示例通常用于以依赖于区域设置的方式显示文本或数字。 包括CurrencyNameProvider Currency 在致电 Currency#getDisplayName 时使用。

查找实施

希望使用特定LocaleServiceProvider(例如CurrencyNamePovider)的类使用LocaleServiceProviderPool来查找支持特定区域设置的提供程序的实例。

LocaleServiceProviderPool尝试首先使用JRE中包含的默认实现。如果找不到,它依赖于Java中的简单服务提供者接口(SPI)机制,并使用ServiceLoader 1 来尝试查找由第三个提供的实现党的图书馆

这是tutorial about Locale

中的内容
  

这些方法首先检查Java运行时环境是否支持所请求的语言环境;如果是这样,他们会使用这种支持。否则,这些方法会调用已安装的提供程序的getAvailableLocales()方法,以找到支持所请求区域设置的提供程序。

可以在包sun.util.locale.provider中找到JRE附带的提供程序的默认实现。它很复杂,但它基本上从jar localedata.jar获取数据。在Oracle JDK中,它位于java_home/jre/lib/ext/localedata.jar。如果列出此jar中的文件,并检查sun.util.resources.essun.util.resources.ru中的文件,您将看到为西班牙语定义的货币名称多于俄语。

以下是OpenJDK的文件:Russian vs Spanish

如果没有定义怎么办

区域设置按层次结构组织。例如,某个国家/地区的特定区域可以有一个区域设置,该区域设置反映了该国家/地区的一些本地差异。如果找不到区域设置的数据,LocaleServiceProviderPool将尝试使用区域设置的父级。

Locales树的根基本上是一个“后备”虚构的Locale,它为所有本地化数据提供默认值。

当你要求用俄语显示美元的显示名称时,可能会发生这种情况。

扩展

任何程序都可以提供其他语言环境信息。他们需要通过创建元数据文件并实现CurrencyNameProvider来定义服务提供者 1 。您可以在自己的jar中填写缺少的本地化数据。

结论

  

或者Java还没有翻译它?

情况就是这样。

  

或者我做错了什么?

不,您可以依靠默认值或自己提供本地化数据。

1 ServiceLoader会通过要求类加载器加载资源META-INF/services/java.text.spi.DateFormatProvider来找到它们。如果找到这样的文件,它应该具有该实现的特定类名。然后它尝试通过类加载器创建它的实例。