首页 > 解决方案 > ResourceBundle - 属性文件继承

问题描述

我正在设置 ResourceBundle,但我得到了不符合 Oracle 文档的奇怪结果。https://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s1804resourcebundleinheritance01.html

我有 3 个文件:

Animals_fr.properties

name=animals_fr

Animals_en.propertis

name=animals_en
age=5

动物.properties

name=animals
age=0

然后我有代码:

Locale localeFr = new Locale("fr");
Locale.setDefault(new Locale("en","US"));
ResourceBundle b = ResourceBundle.getBundle("Animals", localeFr);
System.out.println(b.getString("name"));
System.out.println(b.getString("age"));

基于Oracle的文档继承应该是这样的:

Animals_fr - locale bundle
Animals_en - default locale bundle
Animals - default bundle

结果应该是:

animals_fr
5

但我得到了结果:

animals_fr
0

有什么想法有什么问题吗?

谢谢

标签: javajava-8sdkresourcebundle

解决方案


您链接的文档描述了如何查找资源包,而不是如何解析单个资源键。

这符合记录的默认行为,其中说

如果指定语言环境的语言、脚本、国家和变体都是空字符串,则基本名称是唯一的候选包名称。否则,将根据指定区域设置(语言、脚本、国家和变体)的属性值生成候选区域设置列表,并将其附加到基本名称。

它描述了单个如何Locale导致一系列候选名称。在你的情况下,它只是[ Animal_Fr ]. 然后,它说:

这一直持续到结果资源包被实例化或候选包名称列表用完为止。如果没有找到匹配的资源包,getFallbackLocale则调用默认控件的方法,该方法返回当前的默认语言环境。使用此语言环境生成一个新的候选语言环境名称序列,并再次搜索,如上所述。

因此,如果Animal_Fr不存在,它确实会回退到默认语言环境,尝试使用[ Animals_en_US, Animals_en ].

但是由于Animal_Fr确实存在并且可以被实例化,所以这个查找将不会继续。相反,为了查找特定的资源键,链接变得相关,这被记录为:

一旦找到结果资源包,就会实例化其父链。如果结果包已经有一个父级(可能是因为它是从缓存中返回的),则链是完整的。

否则,getBundle检查在生成结果资源包的过程中使用的候选语言环境列表的其余部分。[...] 当涉及到候选列表的末尾时,它会尝试普通的包名称。对于每个候选包名称,它都会尝试实例化一个资源包 […]。

无论何时成功,它都会setParent使用新的资源包调用先前实例化的资源包的方法。这一直持续到名称列表用完或当前捆绑包已经有一个非空父级。

因此,链接的文档对于 的整体行为是正确的getBundle,这是文档中描述的两步过程的结果。但是当涉及到与 的行为相关的父链时getString,只会使用当前查找阶段的候选列表。

因此,根据确实存在哪些实际捆绑包,它最终可能会出现

Animals_fr ‣ Animals

或者

Animals_en_US ‣ Animals_en ‣ Animals

在您的示例设置中。


推荐阅读