java.util.Locale有一个空的第一项

我试图从JVM获取所有语言环境以填充国家/地区下拉列表。 第一项是空的非null对象。 它不是null,因为我使用TreeMap集合添加国家缩写和(可显示)名称。 看下面看看这个系列是什么。

{=, AE=United Arab Emirates, AL=Albania, AR=Argentina, AT=Austria, AU=Australia, BA=Bosnia and Herzegovina, BE=Belgium, BG=Bulgaria, BH=Bahrain, BO=Bolivia, BR=Brazil,.... 

这是代码。 我删除该空对象以确保第一个值不为空。

 public Map countries(Locale currentLocale) { Map countries = new TreeMap(); for (Locale locale : Locale.getAvailableLocales()) { countries.put(locale.getCountry(), locale.getDisplayCountry(currentLocale)); } countries.remove(""); return countries; } 

JVM版本 – (build 1.7.0_09-b05)

javadocs基本上涵盖了这一点。

对于locale.getCountry()您会发现:

返回此语言环境的国家/地区代码,该代码应为空字符串 ,大写ISO 3166 2字母代码或UN M.49 3位代码。

对于locale.getDisplayCountry()您会发现:

返回适合显示给用户的语言环境国家/地区的名称。 如果可能,返回的名称将针对默认语言环境进行本地化。 例如,如果语言环境是fr_FR且默认语言环境是en_US,则getDisplayCountry()将返回“France”; 如果语言环境是en_US且默认语言环境是fr_FR,则getDisplayCountry()将返回“Etats-Unis”。 如果返回的名称无法针对默认语言环境进行本地化(例如,我们没有克罗地亚的日语名称),则此函数将返回英语名称,并使用ISO代码作为最后的值。 如果语言环境未指定国家/地区,则此函数返回空字符串。

你不能“看到”的那个没有ISO代码而又回到那个,因为它无法本地化到你的语言环境而且也没有英文名称(或者没有国家/地区名称)指定)。 对于你来说两者都是空字符串是完全有效的(尽管,相当无用)。

有问题的语言环境莫过于Locale.ROOT 。 locale == Locale.ROOT就在我的最后,我认为对你来说也是如此。

为什么Locale.ROOT存在? 根据http://www.oracle.com/technetwork/java/javase/java8locales-2095355.html :

如果没有指定的语言环境提供程序支持所请求的语言环境,则使用默认的“JRE”语言环境提供程序的Locale.ROOT语言环境资源。 例如,如果在“java.locale.providers”系统属性中仅指定了“CLDR”,则Collat​​or的工作方式与ROOT语言环境请求的一样,因为“CLDR”语言环境提供程序不提供Collat​​or语言环境数据。 指定“CLDR,JRE”补充了“JRE”语言环境提供程序的Collat​​orfunction,并且更喜欢“CLDR”语言环境提供程序的其他语言环境数据到“JRE”的语言环境提供程序。

尝试

  for (Locale locale : Locale.getAvailableLocales()) { System.out.println(locale.getLanguage() + " " + locale.getCountry()); } 

你会看到一些语言环境只有语言,没有国家

 ms MY ar QA is IS fi FI pl en MT ...