处理复合消息
原文: https://docs.oracle.com/javase/tutorial/i18n/format/messageFormat.html
复合邮件可能包含多种变量:日期,时间,字符串,数字,货币和百分比。要以与语言环境无关的方式格式化复合邮件,可以构造应用于MessageFormat对象的模式,并将此模式存储在ResourceBundle中。
通过单步调试示例程序,本节演示了如何使复合邮件国际化。示例程序使用 MessageFormat 类。该程序的完整源代码位于名为 MessageFormatDemo.java 的文件中。德语语言环境属性位于名为 MessageBundle_de_DE.properties 的文件中。
1.识别消息中的变量
假设您要国际化以下消息:

请注意,我们已经为变量数据加下划线,并确定了哪种对象将代表这些数据。
2.隔离 ResourceBundle 中的消息模式
将消息存储在名为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数组中保存参数值的元素的索引相匹配。请注意,在模式中,参数编号不是任何特定顺序。您可以将参数放在模式中的任何位置。唯一的要求是参数号在参数值数组中具有匹配元素。
下一步讨论参数值数组,但首先让我们看一下模式中的每个参数。下表提供了有关参数的一些详细信息:
Arguments for template in MessageBundle_en_US.properties
| 争论 | 描述 |
| —- | —- |
| {2,time,short} | Date对象的时间部分。 short样式指定DateFormat.SHORT格式样式。 |
| {2,date,long} | Date对象的日期部分。相同的Date对象用于日期和时间变量。在Object参数数组中,保存Date对象的元素的索引是 2.(这将在下一步中介绍。) |
| {1,number,integer} | 一个Number对象,进一步使用integer编号样式限定。 |
| {0} | ResourceBundle中与planet键对应的String。 |
有关参数语法的完整说明,请参阅 MessageFormat 类的 API 文档。
3.设置消息参数
以下代码行为模式中的每个参数赋值。 messageArguments数组中元素的索引与模式中的参数号匹配。例如,索引 1 处的Integer元素对应于模式中的{1,number,integer}参数。因为必须进行转换,所以元素 0 处的String对象将使用getString方法从ResourceBundle中获取。以下是定义消息参数数组的代码:
Object[] messageArguments = {messages.getString("planet"),new Integer(7),new Date()};
4.创建格式化程序
接下来,创建一个MessageFormat对象。您设置Locale,因为该消息包含Date和Number对象,这些对象应以区域设置敏感的方式格式化。
MessageFormat formatter = new MessageFormat("");formatter.setLocale(currentLocale);
5.使用模式和参数格式化消息
此步骤显示模式,消息参数和格式化程序如何一起工作。首先,使用getString方法从ResourceBundle中获取模式String。模式的关键是template。使用applyPattern方法将模式String传递给格式化程序。然后通过调用format方法使用消息参数数组格式化消息。 format方法返回的String已准备好显示。所有这一切都只需两行代码即可完成:
formatter.applyPattern(messages.getString("template"));String output = formatter.format(messageArguments);
6.运行演示程序
演示程序打印英语和德语语言环境的翻译消息,并正确格式化日期和时间变量。请注意,英语和德语动词(“detected”和“entdeckt”)位于相对于变量的不同位置:
currentLocale = en_USAt 10:16 AM on July 31, 2009, we detected 7spaceships on the planet Mars.currentLocale = de_DEUm 10:16 am 31\. Juli 2009 haben wir 7 Raumschiffeauf dem Planeten Mars entdeckt.
