如何忽略ResourceBundle.getBundle中的defaultLocale?

时间:2018-01-10 14:15:12

标签: java locale resourcebundle

目前我正在学习i18n并发现

返回的Locale
Locale.getDefault()

影响资源的查找过程。该示例取自The Java™ Tutorials - A Quick Example稍加修改:

org.i18n.I18NSample

package org.i18n;

import java.util.*;

public class I18NSample {

    static public void main(String[] args) {

        String language;
        String country;

        if (args.length != 2) {
            language = new String("en");
            country = new String("US");
        } else {
            language = new String(args[0]);
            country = new String(args[1]);
        }

        Locale defaultLocale = Locale.getDefault();
        System.out.println("default language = " + defaultLocale.getLanguage()
                  + "; default country = " + defaultLocale.getCountry());

        Locale inputLocale = new Locale(language, country);
        System.out.println("input language = " + inputLocale.getLanguage()
                  + "; input country = " + inputLocale.getCountry());

        ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", inputLocale);
        Locale bundleLocale = messages.getLocale();
        System.out.println("bundle language = " + bundleLocale.getLanguage()
                  + "; bundle country = " + bundleLocale.getCountry());

        System.out.println(messages.getString("greetings"));
        System.out.println(messages.getString("inquiry"));
        System.out.println(messages.getString("farewell"));
    }
}

已定义默认资源 MessagesBundle.properties

greetings = Hello.
farewell = Goodbye.
inquiry = How are you?

和3个额外的资源文件

MessagesBundle_de_DE.properties

greetings = Hallo.
farewell = Tschüß.
inquiry = Wie geht's?

MessagesBundle_en_US.properties

greetings = Hi.
farewell = Bye-bye.

MessagesBundle_fr_FR.properties

greetings = Bonjour.
farewell = Au revoir.
inquiry = Comment allez-vous?

直到现在一切都是O.K. java -jar I18nFirstTest.jar fr FR给出:

default language = pl; default country = PL
input language = fr; input country = FR
bundle language = fr; bundle country = FR
Bonjour.
Comment allez-vous?
Au revoir.

java -jar I18nFirstTest.jar nl NL给出:

default language = pl; default country = PL
input language = nl; input country = NL
bundle language = ; bundle country =
Hello.
How are you?
Goodbye.

现在,我添加以下资源文件 MessagesBundle_pl_PL.properties

farewell = Do widzenia.
greetings = Dzie\u0144 dobry.
inquiry = \u0104\u0105\u0106\u0107\u0118\u0119\u0141\u0142\u0143\u0144Óó\u015A\u015B\u0179\u017A\u017B\u017C

出现问题java -jar I18nFirstTest.jar nl NL给出:

default language = pl; default country = PL
input language = nl; input country = NL
bundle language = pl; bundle country = PL
Dzień dobry.
ĄąĆćĘꣳŃńÓ󌜏źŻż
Do widzenia.

此处描述了在捆绑中设置 pl_PL 的原因public static ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) - 提取:

If no matching resource bundle is found, the default control's
getFallbackLocale method is called, which returns the current
default locale. A new sequence of candidate locale names is
generated using this locale and and searched again, as above. 

并且默认语言环境确实是 pl_PL ,但这是 NOT 我想通过设计获得的内容 - >有默认资源,对吧?

问题:
如何删除getBundle方法的功能,它使用我的默认语言环境处理第二次查找?

我不想将我的语言环境更改为Locale.setDefault(new Locale("en", "GB")),因为它会影响其他模块的功能

在语言环境之间切换也可能不是线程安全操作(对吗?)

...
    Locale defaultLocale = Locale.getDefault();
    Locale.setDefault(new Locale("en", "GB"));
    ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", inputLocale);
    Locale.setDefault(defaultLocale);
...

那么解决方案是什么?

1 个答案:

答案 0 :(得分:0)

加载资源包时,Java基本上首先检查是否存在所请求语言环境的包,然后如果存在默认语言环境的包,并且如果它们都不存在,则返回基本包({{1 }})。

如您引用的文档片段中所述,默认语言环境由Locale("")控制方法提供。 getFallbackLocale()提供了一个控制进程的静态ResourceBundle类。加载Control时默认使用它,但您也可以提供自己的ResourceBundle实现。

您的情况应该足够:

Control

因为该方法返回null public class ModifiedControl extends ResourceBundle.Control { @Override public Locale getFallbackLocale( String aBaseName, Locale aLocale ) { if( aBaseName == null || aLocale == null ) { throw new NullPointerException(); } return null; } } 将返回默认资源。

  

[...]
  5.调用control.getFallbackLocale方法以获取后备区域设置(替代当前目标区域设置)以进一步尝试   寻找资源包。如果该方法返回非null语言环境,则为   成为下一个目标语言环境,加载过程重新开始   从第3步开始。否则,如果找到了一个基础包并将其搁置   在前面的步骤5中,它现在返回给调用者。否则,一个   抛出MissingResourceException   [...]
  来源:https://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String,%20java.util.Locale,%20java.lang.ClassLoader,%20java.util.ResourceBundle.Control)

然后,您必须在加载资源包时提供已修改控件的实例。

ResourceBundle
相关问题