确定要在 Java 8 中使用的资源包

Determining which Resource Bundle to use in Java 8

我有 3 个资源包 (RB) 属性文件:RB_en, RB_fr and RB。我将默认区域设置设置为“en_US”,现在我使用 getBundle("RB", new Locale("fr")) 获取键“key1”的值。我知道 Java 将首先查找属性文件 RB_fr,但是如果在 RB_fr 中找不到键“key1”,那么在它会继续寻找哪个订单? RB_en 文件还是 RB 文件?

所以这里有一些演示代码:

RB.properties: key1 = valueRB

RB_en.properties: key1 = valueRB_en

RB_fr.properties:key2=值RB_fr

 Locale fr = new Locale("fr");
 Locale.setDefault(new Locale("en", "US"));
 ResourceBundle b = ResourceBundle.getBundle("RB", fr);
 b.getString("key1");

看了一本书,OCP Java SE 8 Programmer II,上面说顺序会是RB_fr -> RB_en -> RB。但是我运行测试的时候,显示的顺序是RB_fr -> RBRB_en竟然没有考虑。所以这让我有点困惑,谁能解释一下哪个顺序是正确的?

你必须区分缺少 捆绑包 和缺少 密钥

您首先使用 getBundle 请求法语资源包。这种查找确实如书中和相应的 javadoc 中所述:

getBundle uses the base name, the specified locale, and the default locale (obtained from Locale.getDefault) to generate a sequence of candidate bundle names.

...

getBundle then iterates over the candidate bundle names to find the first one for which it can instantiate an actual resource bundle.

由于 RB_fr.properties 存在,它将找到并实例化它。

您随后使用 getString 请求键 key1 的值。但除了 getBundle 之外,它没有回退到默认语言环境。它会在当前包和任何 parent 中查找:

Gets a string for the given key from this resource bundle or one of its parents.

您的法语包的 parent 是基本包(即 RB.properties),这解释了为什么您看不到英语值(parent chain 在上面链接的 getBundle 的 javadoc 中也有一些详细的解释。

如果你是,你会观察到预期的行为。寻找德语资源包:

ResourceBundle b = ResourceBundle.getBundle("RB", new Locale("de"));
b.getString("key1"); // valueRB_en

在那种情况下,getBundle 将找不到任何 RB_de.properties 并回退到 RB_en.properties,其中存在 key1 并将被返回。