Ock
Ock

Reputation: 1330

Determining which Resource Bundle to use in Java 8

I have 3 Resource Bundle (RB) properties file: RB_en, RB_fr and RB. I set a default Locale of "en_US" and now I use getBundle("RB", new Locale("fr")) to get value for a key "key1". I know that Java will look first for the properties file RB_fr, but if the key "key1" is not found in RB_fr, then in which oder will it continue looking? the RB_en file or RB file?.

So here some demo code:

RB.properties: key1 = valueRB

RB_en.properties: key1 = valueRB_en

RB_fr.properties: key2 = valueRB_fr

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

I read a book, the OCP Java SE 8 Programmer II, it said that the order will be RB_fr -> RB_en -> RB. But when I run a test, the order it shown was RB_fr -> RB, the RB_en even didn't take into account. So this make me a bit confused, can anyone explain me which order is correct?

Upvotes: 2

Views: 1252

Answers (1)

Marvin
Marvin

Reputation: 14255

You have to distinguish between missing bundles and missing keys.

You are first requesting the French resource bundle using getBundle. This lookup is indeed as described in the book and in the corresponding 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.

Since RB_fr.properties is present, it will find and instantiate that.

You are then requesting the value for key key1 using getString. But other than getBundle this does not have a fallback to a default locale. It looks in the current bundle and in any parents only:

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

The parent of your French bundle is the base bundle (i.e. RB.properties), which explains why you are not seeing the English value (the parent chain is also explained in some detail in getBundle's javadoc linked above).

You would observe the expected behaviour if you were e.g. looking for a German resource bundle:

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

In that case getBundle would not find any RB_de.properties and fall back to RB_en.properties where key1 is present and would be returned.

Upvotes: 2

Related Questions