我应该将java.text.MessageFormat用于没有占位符的本地化消息吗?

我们正在为在Java 5上运行的Web应用程序本地化用户界面文本,并且我们如何输出在属性文件中定义的消息( java.util.Properties使用的类型)的困境。

某些消息包含将使用java.text.MessageFormat填充的占位符。 例如:

search.summary = Your search for {0} found {1} items. 

MessageFormat很烦人,因为单引号是一个特殊字符,尽管在英文文本中很常见。 你必须输入两个文字单引号:

 warning.item = This item''s {0} is not valid. 

但是,应用程序的1000个左右的消息中有四分之三不包含占位符。 这意味着我们可以直接输出它们,避免使用MessageFormat,并保留单引号:

 help.url = The web page's URL 

问题:我们应该为所有消息使用MessageFormat,以获得一致的语法,还是尽可能避免使用MessageFormat,因此大多数消息都不需要转义?

无论哪种方式都有明显的优点和缺点。

请注意,MessageFormat的API文档确认了该问题,并建议使用非解决方案:

遗憾的是,在消息格式模式中使用引号的规则已经显得有些混乱。 特别是,对于本地化者来说,单引号是否需要加倍并不总是显而易见的。 确保通知本地化程序有关规则,并告诉它们(例如,通过在资源包源文件中使用注释)MessageFormat将处理哪些字符串。

只需编写自己的MessageFormat实现,而不需要这个烦人的function。 您可以查看SLF4J Logger的代码。

他们有自己版本的消息格式化程序,可以按如下方式使用:

 logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT); 

空占位符可以与默认排序一起使用,并编号用于一些本地化案例,其中不同的语言对单词或句子的部分进行排列。

最后,我们决定通过始终使用“curl”引号来支持单引号问题:

 warning.item = This item\u2019s {0} is not valid. 

使用`character而不是’来引用。 我们一直使用它没有问题。

仅在需要时使用MessageFormat,否则它们只会膨胀代码并且没有额外的值。

在我看来,一致性对于这类事情很重要。 属性文件和MessageFormat已经有很多限制。 如果您发现这些麻烦,您可以“编译”您的属性文件以生成正确形成的属性文件。 但我会说到处都使用MessageFormat。 这样,在维护代码时,您不必担心格式化哪些字符串,哪些字符串不格式化。 处理起来变得更加简单,因为您可以将消息处理交给库,而不必担心高级别的细节。

另一种选择……当加载属性文件时,只需将输入流包装在一个FilterInpuStream中,它将每个引用加倍。