该Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言功能的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
一个复合消息可以包含多种类型的变量:日期、时间、字符串、数字、货币和百分比。为了以与语言环境无关的方式格式化复合消息,您需要构建一个应用于MessageFormat
对象的模式,并将此模式存储在ResourceBundle
中。
通过步骤演示一个示例程序,本节展示了如何国际化一个复合消息。示例程序使用了MessageFormat
类。完整的源代码在名为MessageFormatDemo.java
的文件中。德国语言环境的属性存储在名为MessageBundle_de_DE.properties
的文件中。
假设您想国际化以下消息:
请注意,我们已经用下划线标出了变量数据,并确定了将表示这些数据的对象的类型。
将消息存储在名为MessageBundle
的ResourceBundle
中,如下所示:
ResourceBundle messages = ResourceBundle.getBundle("MessageBundle", currentLocale);
这个ResourceBundle
是由每个Locale
对应的属性文件支持的。由于ResourceBundle
名为MessageBundle
,所以美国英语的属性文件名为MessageBundle_en_US.properties
。该文件的内容如下:
template = At {2,time,short} on {2,date,long}, \ we detected {1,number,integer} spaceships on \ the planet {0}. planet = Mars
属性文件的第一行包含消息模式。如果将此模式与步骤1中显示的消息文本进行比较,您会发现模式中的每个变量都用括号括起来的参数替换了。每个参数都以一个数字(参数编号)开始,该数字与保存参数值的Object
数组中的元素索引匹配。请注意,在模式中,参数编号没有特定的顺序。您可以将参数放置在模式的任何位置。唯一的要求是参数编号在参数值数组中有匹配的元素。
接下来的步骤讨论了参数值数组,但首先让我们来看一下模式中的每个参数。下表提供了关于参数的一些详细信息:
参数 | 描述 |
---|---|
{2,time,short} |
Date 对象的时间部分。 short 样式指定DateFormat.SHORT 格式样式。 |
{2,date,long} |
Date 对象的日期部分。相同的Date 对象用于日期和时间变量。在参数的Object 数组中,保存Date 对象的元素的索引是2。(这在下一步中描述。) |
{1,number,integer} |
Number 对象,进一步指定integer 数字样式。 |
{0} |
与planet 键对应的ResourceBundle 中的String 。 |
有关参数语法的完整描述,请参阅MessageFormat类的API文档。
以下代码行为模式中的每个参数分配值。 messageArguments
数组中元素的索引与模式中的参数编号相匹配。例如,索引1处的Integer
元素对应模式中的{1,number,integer}
参数。因为需要翻译,所以索引0处的String
对象将使用getString
方法从ResourceBundle
中获取。以下是定义消息参数数组的代码:
Object[] messageArguments = { messages.getString("planet"), new Integer(7), new Date() };
接下来,创建一个MessageFormat
对象。您设置Locale
,因为消息包含应以区域敏感方式格式化的Date
和Number
对象。
MessageFormat formatter = new MessageFormat(""); formatter.setLocale(currentLocale);
此步骤展示了模式、消息参数和格式化程序之间的协作。首先,使用getString
方法从ResourceBundle
中获取模式String
。模式的键是template
。将模式String
传递给格式化程序的applyPattern
方法。然后,通过调用format
方法,使用消息参数数组格式化消息。format
方法返回的String
已经准备好显示。所有这些都只需要两行代码完成:
formatter.applyPattern(messages.getString("template")); String output = formatter.format(messageArguments);
演示程序打印了英语和德语环境下的翻译消息,并正确格式化日期和时间变量。请注意,英语和德语的动词("detected"和"entdeckt")相对于变量位置不同:
currentLocale = en_US 在2009年7月31日上午10:16,我们检测到了7艘太空飞船在火星上。 currentLocale = de_DE Um 10:16 am 31. Juli 2009 haben wir 7 Raumschiffe auf dem Planeten Mars entdeckt.