当使用以下语言代码之一实例化Locale
对象时:he
、yi
和id
,它不会保留它们的值。
例如:
Locale locale = new Locale("he", "il");
locale.getLanguage(); // -> "iw"
是什么导致了这个问题,有什么方法可以解决这个问题吗?
发布于 2012-12-20 14:21:54
Locale类不会对您输入的内容进行任何检查,但它会用某些语言代码替换它们的旧值。来自the documentation
ISO639不是一个稳定的标准;它定义的一些语言代码(特别是"iw“、"ji”和"in")已经发生了变化。此构造函数接受旧代码("iw“、"ji”和"in")和新代码("he“、"yi”和"id"),但所有其他语言环境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
类,所以您不能扩展它,而且它也没有特定的接口来实现。让它保留这些语言代码的一种方法是在这个类周围创建一个包装器并使用它。
发布于 2022-01-27 09:10:02
在Java17中,对希伯来语语言环境的Java处理似乎发生了更改。这似乎是一种遵守ISO_639-1语言代码标准的尝试。
除非属性'java.locale.useOldISOCodes‘设置为true,否则Java现在将希伯来语区域设置视为符合ISO639-1的'he’。这意味着您将成功加载一个名为'messages_he.properties‘的希伯来语资源包,其中包含'iw’或'he‘语言代码构造的语言环境。'messages_iw.properties‘资源被取消优先级,并且仅当对应的'he’资源不存在时才会被加载。
这是朝着正确方向迈出的一步,迟到总比不到好,因为在希伯来语资源包的命名策略中不需要更多的花招和魔法。只要使用'he‘ISO代码即可。
我最近在Locale code for Hebrew / Reference to other locale codes?回答了这个问题。我提供了一个带有基本资源包的小示例类,它演示了新的行为。
https://stackoverflow.com/questions/13974169
复制相似问题