6

在我的应用程序中,我使用 java 资源包来翻译它的标签。我目前有两个文件:

  • resources.properties 带有英文标签(默认语言)
  • resources_fr.properties 带有法语标签

然后,我使用以下命令加载包属性:

ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale);

...locale用户的语言环境在哪里。

当我使用法语网络浏览器时,没关系,我收到的所有消息都是法语,因为我的语言环境正确设置为 fr。但是当我将浏览器切换到美国英语时,它们仍然是法语!

locale变量已使用 en_US 语言环境正确设置,但该getBundle方法返回一个带有 fr 语言环境的包,而不是只返回默认包...

这是正常行为吗?我很惊讶,因为我期望在resources.properties语言环境没有附加特定资源包(如法语)时使用英语值...

4

2 回答 2

4

这是正常结果,但如果您没有仔细阅读getBundle的(相当冗长的)描述,这还是相当令人惊讶的。重要的部分是:

如果没有找到匹配的资源包,则调用默认控件的 getFallbackLocale 方法,该方法返回当前的默认语言环境。使用此语言环境生成一个新的候选语言环境名称序列,并再次搜索,如上所述。

这有点出乎意料。只有在尝试了除了指定语言环境之外的默认语言环境之后,该方法才会执行您期望的操作:

如果仍然没有找到结果包,则仅查找基本名称。

这是桌面应用程序的合理行为。毕竟,如果您在给定机器默认语言环境的情况下成功启动了 Java 应用程序,那么您应该知道如果应用程序使用默认语言环境而不是您指定的语言环境出现时如何处理该应用程序。但是,如果您的应用程序是一个 Web 服务器,并且使用服务器的区域设置而不是您在浏览器中指定的首选项,那么生成的页面可能会非常令人困惑。

处理此问题的正确方法是禁止使用回退语言环境。您可以通过指定附加参数在代码中执行此操作ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_DEFAULT),从而导致

ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale, 
    ResourceBundle.Control.getNoFallbackControl(
        ResourceBundle.Control.FORMAT_DEFAULT));

(当我不止一次需要此参数时,我通常会在某处为附加参数定义一个常量。)这会导致您所期望的行为。

于 2017-07-03T16:47:53.527 回答
0

这可能有助于澄清您的问题:

http://docs.oracle.com/javase/tutorial/i18n/resbundle/propfile.html

这些 Locale 对象应该与前两个步骤中创建的属性文件相匹配。例如,Locale.FRENCH 对象对应于 LabelsBundle_fr.properties 文件。Locale.ENGLISH 没有匹配的 LabelsBundle_en.properties 文件,因此将使用默认文件。

于 2013-07-25T12:48:59.157 回答