为什么某些显示名称以英语显示,尽管语言环境不是英语(即:未翻译)。
例如: 地区:" 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没有得到翻译它?
或者我做错了什么?
我试图找到存储这些翻译但无法找到它们的文件。如果有人能指出我那个有用的资源。
感谢。
答案 0 :(得分:13)
Java使用可扩展的机制来提供数据(例如字符串, 格式化程序等)本地化。
类可以实现
LocaleServiceProvider
成为工厂 本地敏感数据。java.util
和java.text
中的很多课程 依靠这些提供商与不同的Locale
合作 委托创建对象。
您可以在java.util.spi
包中找到本地服务提供商的示例,这些示例通常用于以依赖于区域设置的方式显示文本或数字。 包括CurrencyNameProvider
, Currency
在致电 Currency#getDisplayName
时使用。
希望使用特定LocaleServiceProvider
(例如CurrencyNamePovider
)的类使用LocaleServiceProviderPool
来查找支持特定区域设置的提供程序的实例。
LocaleServiceProviderPool
尝试首先使用JRE中包含的默认实现。如果找不到,它依赖于Java中的简单服务提供者接口(SPI)机制,并使用ServiceLoader
1 来尝试查找由第三个提供的实现党的图书馆。
这些方法首先检查Java运行时环境是否支持所请求的语言环境;如果是这样,他们会使用这种支持。否则,这些方法会调用已安装的提供程序的getAvailableLocales()方法,以找到支持所请求区域设置的提供程序。
可以在包sun.util.locale.provider
中找到JRE附带的提供程序的默认实现。它很复杂,但它基本上从jar localedata.jar
获取数据。在Oracle JDK中,它位于java_home/jre/lib/ext/localedata.jar
。如果列出此jar中的文件,并检查sun.util.resources.es
和sun.util.resources.ru
中的文件,您将看到为西班牙语定义的货币名称多于俄语。
以下是OpenJDK的文件:Russian vs Spanish。
区域设置按层次结构组织。例如,某个国家/地区的特定区域可以有一个区域设置,该区域设置反映了该国家/地区的一些本地差异。如果找不到区域设置的数据,LocaleServiceProviderPool
将尝试使用区域设置的父级。
Locales树的根基本上是一个“后备”虚构的Locale,它为所有本地化数据提供默认值。
当你要求用俄语显示美元的显示名称时,可能会发生这种情况。
任何程序都可以提供其他语言环境信息。他们需要通过创建元数据文件并实现CurrencyNameProvider
来定义服务提供者 1 。您可以在自己的jar中填写缺少的本地化数据。
或者Java还没有翻译它?
情况就是这样。
或者我做错了什么?
不,您可以依靠默认值或自己提供本地化数据。
1 ServiceLoader
会通过要求类加载器加载资源META-INF/services/java.text.spi.DateFormatProvider
来找到它们。如果找到这样的文件,它应该具有该实现的特定类名。然后它尝试通过类加载器创建它的实例。