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