java - 如何理解Java教程国际化定制资源包加载示例?

标签 java internationalization locale resourcebundle

我从 Oracle Java 教程中看到了这段代码,但我对它的实际工作原理感到困惑。我正在寻找几个问题的答案:

1) 我没看到 public List<Locale> getCandidateLocales(String baseName, Locale locale)从任何地方调用,那么它实际上是如何执行的呢?

2) 作为参数传递给 public List<Locale> getCandidateLocales(String baseName, Locale locale) 的内容

3) public List<Locale> getCandidateLocales(String baseName, Locale locale)返回 List<Locale> ,返回 List<Locale> 的目的是什么?

4) public List<Locale> getCandidateLocales(String baseName, Locale locale)返回super.getCandidateLocales(baseName, locale);如果if都没有满足语句,那么关键字super指的是哪个类?

public class RBControl {
    public static void main(String[] args) {
    test(Locale.CHINA);
    test(new Locale("zh", "HK"));
    test(Locale.TAIWAN);
    test(Locale.CANADA);
    }

    private static void test(Locale locale) {
    ResourceBundle rb = ResourceBundle.getBundle("Internationalisation/RBControl", locale,
         new ResourceBundle.Control() {
         @Override
         public List<Locale> getCandidateLocales(String baseName, Locale locale) {
             if (baseName == null)
             throw new NullPointerException();
             if (locale.equals(new Locale("zh", "HK"))) {
             return Arrays.asList(
                 locale,
                 Locale.TAIWAN,
                 // no Locale.CHINESE here
                 Locale.ROOT);
             } else if (locale.equals(Locale.TAIWAN)) {
             return Arrays.asList(
                 locale,
                 // no Locale.CHINESE here
                 Locale.ROOT);
             }
             return super.getCandidateLocales(baseName, locale);
         }
         });
    System.out.println("locale: " + locale);
    System.out.println("\tregion: " + rb.getString("region"));
    System.out.println("\tlanguage: " + rb.getString("language"));
    }
}

最佳答案

老实说,可能很难回答您的问题,因为您的代码风格早于 Java 7(您是考古学家吗?),但我会尝试。

  1. 我只能向你保证getCandidateLocales(String, String)当代码搜索有效的文件名或类名以从中加载文本资源时实际上会调用。例如:

    // ResourceBundle.java line 1314
    private static ResourceBundle getBundleImpl(String baseName, Locale locale,
                                                ClassLoader loader, Control control) {
        // (...) many lines removed
        // line 1352 - loop through files to find the best one
        ResourceBundle baseBundle = null;
        for (Locale targetLocale = locale;
             targetLocale != null;
             targetLocale = control.getFallbackLocale(baseName, targetLocale)) {
            // line 1356, there you are
            List<Locale> candidateLocales = control.getCandidateLocales(baseName, targetLocale);
            if (!isKnownControl && !checkList(candidateLocales)) {
                throw new IllegalArgumentException("Invalid Control: getCandidateLocales");
            }
    
            bundle = findBundle(cacheKey, candidateLocales, formats, 0, control, baseBundle);
    
            // lengthy comment removed for clarity
            if (isValidBundle(bundle)) {
               // checking if it is the right one, removed
            }
        }
    
        // logic to deal with missing file, removed    
        return bundle;
    }
    
  2. 我相信现在应该很明显了,但让我详细介绍一下。假设您的消息采用属性文件的形式:messages.properties - 基础,默认语言资源,messages_fr.properties - 法国基础资源,messages_fr_CA.properties - 法裔加拿大资源最后 messages_de.proprties - 基础德国资源。基本名称正如您可能猜到的基本文件名那样, messages那是。候选区域设置是用户界面区域设置。
    如果您正在开发桌面应用程序(极不可能)或移动应用程序,则只需调用 Locale.getDetault(Locale.Category.DISPLAY) 即可获取 UI 区域设置。 。在旧版本的 Java 中,它只是 Locale.getDefault() 。在 Web 应用程序中,解决方案实际上取决于技术(即 Spring、JSF、Thymeleaf、Play 等)和区域设置检测方法。无论如何,你应该首先尝试最专业的一个,而不是后退。例如,法语加拿大用户(语言标签 fr-CA)应该看到 messages_fr_CA.properties 的内容。 ,而其他法语用户则应获得 messages_fr.properties 的内容。同样,任何其他语言环境,应遵守 messages.properties 中的翻译。 .
    此方法的作用是,它将为用户生成后备语言环境(即,对于输入 Locale.forLanguageTag("fr-CA") 它将返回输入本身、法语语言环境(“fr”)和未定义的语言环境标记(“und”)。其中之一告诉 ResourceBundle 使用默认文件。

  3. 它返回后备语言环境列表,正如我上面所解释的。

  4. 它调用父类中的方法 - ResourceBundle.Control 。您附加的代码 list 中定义的匿名内部类实际上派生自 ResourceBundle.Control .

关于java - 如何理解Java教程国际化定制资源包加载示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36370197/

相关文章:

java - Retrofit2 状态码为 200 但 json 结构不同于数据模型类时的处理条件

java - 算法性能。我解决不了

c - fputs( _ ("") ) 下划线代表什么?

javascript - 继承 Locale 无法正常工作

java - 将文件从 Jenkins 工作区(从 Docker 容器内部)复制到本地驱动器

java - 无法在 AMD 64 位平台 JNI 上加载 IA 32 位 .dll

date - 获取当前语言环境的日期格式

C++ 在 Linux 上编写 UTF-8

java - 在区域设置中设置语言

php - Symfony2 语言环境检测和翻译