如何理解Java教程国际化自定义资源包加载示例?
How to understand the Java tutorial internationalisation Customizing Resource Bundle Loading example?
我从 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)
returns a List<Locale>
, returning a List<Locale>
的目的是什么
4) public List<Locale> getCandidateLocales(String baseName, Locale locale)
return super.getCandidateLocales(baseName, locale);
if none 的if
语句满足,也就是class 关键字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"));
}
}
老实说,可能很难回答您的问题,因为您的代码风格早于 Java7(您是考古学家吗?),但我会尽力。
我只能向您保证 getCandidateLocales(String, String)
实际上是在代码搜索有效文件名或 class 名称以从中加载文本资源时调用的。例如:
// 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;
}
我相信现在应该很明显了,但让我详细介绍一下。假设您的消息以属性文件的形式存在: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")
它将 return 输入本身、法语语言环境("fr")和未定义的语言环境标记("und")。最后一个告诉 ResourceBundle
使用默认文件。
它 return 是后备语言环境列表,正如我上面所解释的。
它调用父 class - ResourceBundle.Control
中的方法。您附加的代码清单中定义的匿名内部 class 实际上派生自 ResourceBundle.Control.
我从 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)
returns a List<Locale>
, returning a List<Locale>
4) public List<Locale> getCandidateLocales(String baseName, Locale locale)
return super.getCandidateLocales(baseName, locale);
if none 的if
语句满足,也就是class 关键字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"));
}
}
老实说,可能很难回答您的问题,因为您的代码风格早于 Java7(您是考古学家吗?),但我会尽力。
我只能向您保证
getCandidateLocales(String, String)
实际上是在代码搜索有效文件名或 class 名称以从中加载文本资源时调用的。例如:// 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; }
我相信现在应该很明显了,但让我详细介绍一下。假设您的消息以属性文件的形式存在:
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")
它将 return 输入本身、法语语言环境("fr")和未定义的语言环境标记("und")。最后一个告诉ResourceBundle
使用默认文件。它 return 是后备语言环境列表,正如我上面所解释的。
它调用父 class -
ResourceBundle.Control
中的方法。您附加的代码清单中定义的匿名内部 class 实际上派生自 ResourceBundle.Control.