Locale
使用以下任一语言代码实例化对象时: he
,yi
并且id
不保留其值。
例如:
Locale locale = new Locale("he", "il");
locale.getLanguage(); // -> "iw"
是什么原因造成的,有什么办法可以解决这个问题?
Locale 类不会对您输入的内容进行任何检查,但它会将某些语言代码替换为其旧值。从文档中:
ISO 639 不是一个稳定的标准;它定义的一些语言代码(特别是“iw”、“ji”和“in”)已经改变。此构造函数接受旧代码(“iw”、“ji”和“in”)和新代码(“he”、“yi”和“id”),但 Locale 上的所有其他 API 将仅返回旧代码。
这是构造函数:
public Locale(String language, String country, String variant) {
this.language = convertOldISOCodes(language);
this.country = toUpperCase(country).intern();
this.variant = variant.intern();
}
这是神奇的方法:
private String convertOldISOCodes(String language) {
// we accept both the old and the new ISO codes for the languages whose ISO
// codes have changed, but we always store the OLD code, for backward compatibility
language = toLowerCase(language).intern();
if (language == "he") {
return "iw";
} else if (language == "yi") {
return "ji";
} else if (language == "id") {
return "in";
} else {
return language;
}
}
它创建的对象是不可变的,因此无法解决此问题。该类也是final
,因此您无法扩展它,并且它没有要实现的特定接口。让它保留这些语言代码的一种方法是围绕这个类创建一个包装器并使用它。
Java 对希伯来语语言环境的处理似乎在 Java 17 中发生了变化。它似乎是为了遵守 ISO_639-1 语言代码标准。
除非属性 ' java.locale.useOldISOCodes ' 设置为true,否则 Java 现在将希伯来语语言环境默认为 'he' 以遵守 ISO_639-1。这意味着您将成功加载名为“ messages_he.properties ”的希伯来语资源包,其中包含“iw”或“he”语言代码构建的语言环境。' messages_iw.properties ' 资源被取消优先级并且只有在相应的'he' 资源不存在时才会被加载。
这是朝着正确方向迈出的一步,迟到总比没有好,因为在希伯来语资源包的命名策略中不需要更多的诡计和魔法。只需使用“他”ISO 代码。
我最近在希伯来语的语言环境代码/参考其他语言环境代码中回答了这个问题?. 我提供了一个带有基本资源包的小示例类,它演示了新行为。