SunのJava1.5では、java.util.ResourceBundle#getBundleでロケールを指定して、リソースを取得しようとした場合。
もし、言語(と国)が一致するリソースが存在しなければ、デフォルトのロケールを使ってリソースを取得してしまう。
仮にリソースとして、
【Messages.properties】 key=test 【Messages_jp.properties】 key=テスト
を定義していた場合。
ResourceBundle jprb = ResourceBundle.getBundle("Messages", new Locale("ja", "JP")); ResourceBundle enrb = ResourceBundle.getBundle("Messages", new Locale("en", "US")); ResourceBundle zhrb = ResourceBundle.getBundle("Messages", new Locale("zh", "CN")); System.out.println(jprb.getLocale() + " > " + jprb.getString("key")); System.out.println(enrb.getLocale() + " > " + enrb.getString("key")); System.out.println(zhrb.getLocale() + " > " + zhrb.getString("key"));
を実行すると、ja_JPがデフォルトのローケールのため、
ja > テスト ja > テスト ja > テスト
となる。
もちろん
【Messages_en.properties】 key=test
を定義すると、
ja > テスト en > test ja > テスト
となる。
このような動作では、例えば日本語だけ定義しておいて、それ以外は全部英語としたい場合など、「Messages.propertiesに、英語のメッセージを設定しておけば、日本以外のロケールの場合は英語になる」というような、動作をさせることができない。
Java6では、ITpro > 「Java SE 6完全攻略」第54回 ResourceBundleの新機能 その2 にあるとおり、
ResourceBundle.Control control = ResourceBundle.Control.getNoFallbackControl( ResourceBundle.Control.FORMAT_DEFAULT ); ResourceBundle jprb = ResourceBundle.getBundle("Messages", new Locale("ja", "JP"), control); ResourceBundle enrb = ResourceBundle.getBundle("Messages", new Locale("en", "US"), control); ResourceBundle zhrb = ResourceBundle.getBundle("Messages", new Locale("zh", "CN"), control); System.out.println(jprb.getLocale() + " > " + jprb.getString("key")); System.out.println(enrb.getLocale() + " > " + enrb.getString("key")); System.out.println(zhrb.getLocale() + " > " + zhrb.getString("key"));
とすることで、
ja > テスト en > test > test
という結果が得られる。
同様の挙動は、Java1.5以前のバージョンでは、下記のようなメソッドで実現できそう。
public static ResourceBundle getBundle(String res, Locale locale) { ResourceBundle bundle = ResourceBundle.getBundle(res, locale); if (bundle.getLocale().getLanguage().equals(locale.getLanguage()) == true) { return bundle; } return ResourceBundle.getBundle(res, new Locale("", "")); }