Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
复合消息可能包含多种变量:日期,时间,字符串,数字,货币和百分比。若要以与语言环境无关的方式格式化复合消息,请构造应用于 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} |
ResourceBundle 中的 String ,对应 planet 键。 |
有关参数语法的完整说明,请参阅 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
。使用 applyPattern
方法将模式 String
传递给格式化程序。然后通过调用 format
方法,使用消息参数数组格式化消息。format
方法返回的 String
已准备好显示。所有这一切都只需两行代码即可完成:
formatter.applyPattern(messages.getString("template")); String output = formatter.format(messageArguments);
演示程序打印英语和德语语言环境的翻译消息,并正确格式化日期和时间变量。请注意,英语和德语动词(“detected”和“entdeckt”)位于相对于变量的不同位置:
currentLocale = en_US At 10:16 AM on July 31, 2009, we detected 7 spaceships on the planet Mars. currentLocale = de_DE Um 10:16 am 31. Juli 2009 haben wir 7 Raumschiffe auf dem Planeten Mars entdeckt.