JavaTM Platform
Standard Ed. 6

java.text
类 MessageFormat

java.lang.Object
  继承者 java.text.Format
      继承者 java.text.MessageFormat
所有已实现的接口:
Serializable, Cloneable

public class MessageFormat
extends Format

MessageFormat 提供了以与语言无关方式生成连接消息的方式。使用此方法构造向终端用户显示的消息。

MessageFormat 获取一组对象,格式化这些对象,然后将格式化后的字符串插入到模式中的适当位置。

注:MessageFormat 不同于其他 Format 类,因为 MessageFormat 对象是用其构造方法之一创建的(而不是使用 getInstance 样式的工厂方法创建的)。工厂方法不是必需的,因为 MessageFormat 本身不实现特定于语言环境的行为。特定于语言环境的行为是由所提供的模式和用于已插入参数的子格式来定义的。

模式及其解释

MessageFormat 使用以下形式的模式:
 MessageFormatPattern:
         String
         MessageFormatPattern FormatElement String

 FormatElement:
         { ArgumentIndex }
         { ArgumentIndex , FormatType }
         { ArgumentIndex , FormatType , FormatStyle }

 FormatType: one of 
         number date time choice

 FormatStyle:
         short
         medium
         long
         full
         integer
         currency
         percent
         SubformatPattern

 String:
         StringPartopt
         String StringPart

 StringPart:
         ''
         ' QuotedString '
         UnquotedString

 SubformatPattern:
         SubformatPatternPartopt
         SubformatPattern SubformatPatternPart

 SubFormatPatternPart:
         ' QuotedPattern '
         UnquotedPattern
 

String 中,"''" 表示单引号。QuotedString 可以包含除单引号之外的任意字符;围绕的单引号被移除。UnquotedString 可以包含除单引号和左花括号之外的任意字符。因此,格式化后消息字符串为 "'{0}'" 的字符串可以写作 "'''{'0}''""'''{0}'''"

SubformatPattern 中,应用了不同的规则。QuotedPattern 可包含除单引号之外的任意字符,但 移除围绕的单引号,因此它们可以由子格式解释。例如,"{1,number,$'#',##}" 将产生一个带井号的数字格式,结果如:"$#31,45"。 UnquotedPattern 可以包含除单引号之外的任意字符,但其中的花括号必须成对出现。例如,"ab {0} de""ab '}' de" 是有效的子格式模式,而 "ab {0'}' de""ab } de" 则是无效的。

警告:
不过,在消息格式模式中使用引号的规则在一定程度上显示混乱。尤其是,本地化程序并不总是清楚单引号是否需要成对。要确保通知本地化程序关于规则的信息,并告诉它们(例如,通过使用资源包源文件中的注释)MessageFormat 将处理哪些字符串。注意,本地化程序在转换后的字符串中必须使用单引号,其中原始版本不包含单引号。

ArgumentIndex 值是使用数字 '0' 到 '9' 表示的非负整数,它表示传递给 format 方法的 arguments 数组的一个索引,或者表示由 parse 方法返回的结果数组的一个索引。

FormatTypeFormatStyle 值用来创建格式元素的 Format 实例。下表显示了值如何映射到 Format 实例。表中没有显示的组合是非法的。SubformatPattern 必须是所使用的 Format 子类的一个有效的模式字符串。

格式类型 格式样式 创建的子格式
null
number NumberFormat.getInstance(getLocale())
integer NumberFormat.getIntegerInstance(getLocale())
currency NumberFormat.getCurrencyInstance(getLocale())
percent NumberFormat.getPercentInstance(getLocale())
SubformatPattern new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))
date DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getDateInstance(DateFormat.LONG, getLocale())
full DateFormat.getDateInstance(DateFormat.FULL, getLocale())
SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())
time DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
full DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
SubformatPattern new SimpleDateFormat(subformatPattern, getLocale())
choice SubformatPattern new ChoiceFormat(subformatPattern)

用法信息

下面给出一些用法例子。当然,在实际的国际化程序中,消息格式模式和其他静态字符串将从资源包中获取。其他参数在运行时动态确定。

第一个例子使用静态的方法 MessageFormat.format,它在内部创建一个只使用一次的 MessageFormat

 int planet = 7;
 String event = "a disturbance in the Force";

 String result = MessageFormat.format(
     "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
     planet, new Date(), event);
 
输出为:
 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7.
 

下面的例子创建了一个可以重复使用的 MessageFormat 实例:

 int fileCount = 1273;
 String diskName = "MyDisk";
 Object[] testArgs = {new Long(fileCount), diskName};

 MessageFormat form = new MessageFormat(
     "The disk \"{1}\" contains {0} file(s).");

 System.out.println(form.format(testArgs));
 
不同 fileCount 值的输出:
 The disk "MyDisk" contains 0 file(s).
 The disk "MyDisk" contains 1 file(s).
 The disk "MyDisk" contains 1,273 file(s).
 

对于更复杂的模式,可以使用 ChoiceFormat 来生成正确的单数和复数形式:

 MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
 double[] filelimits = {0,1,2};
 String[] filepart = {"no files","one file","{0,number} files"};
 ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
 form.setFormatByArgumentIndex(0, fileform);

 int fileCount = 1273;
 String diskName = "MyDisk";
 Object[] testArgs = {new Long(fileCount), diskName};

 System.out.println(form.format(testArgs));
 
不同的 fileCount 值的输出:
 The disk "MyDisk" contains no files.
 The disk "MyDisk" contains one file.
 The disk "MyDisk" contains 1,273 files.
 

如上例所示,可以以编程方式来创建 ChoiceFormat,或使用模式创建。有关更多信息,请参阅 ChoiceFormat

 form.applyPattern(
    "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
 

注:从上面的例子可以看到,由 MessageFormat 中的 ChoiceFormat 所生成的字符串要进行特殊处理;'{' 的出现用来指示子格式,并导致递归。如果 MessageFormatChoiceFormat 都是以编程方式创建的(而不是使用字符串模式),那么要注意不要生成对其自身进行递归的格式,这将导致无限循环。

当一个参数在字符串中被多次解析时,最后的匹配将是解析的最终结果。例如,

 MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
 Object[] objs = {new Double(3.1415)};
 String result = mf.format( objs );
 // result now equals "3.14, 3.1"
 objs = null;
 objs = mf.parse(result, new ParsePosition(0));
 // objs now equals {new Double(3.1)}
 

同样,使用包含同一参数多个匹配项的模式对 MessageFormat 对象进行解析时将返回最后的匹配。例如,

 MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
 String forParsing = "x, y, z";
 Object[] objs = mf.parse(forParsing, new ParsePosition(0));
 // result now equals {new String("z")}
 

同步

消息格式不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的。

另请参见:
Locale, Format, NumberFormat, DecimalFormat, ChoiceFormat, 序列化表格

嵌套类摘要
static class MessageFormat.Field
          在从 MessageFormat.formatToCharacterIterator 返回的 AttributedCharacterIterator 中定义用作属性键的常量。
 
构造方法摘要
MessageFormat(String pattern)
          构造默认语言环境和指定模式的 MessageFormat。
MessageFormat(String pattern, Locale locale)
          构造指定语言环境和模式的 MessageFormat。
 
方法摘要
 void applyPattern(String pattern)
          设置此消息格式所使用的模式。
 Object clone()
          创建并返回此对象的一个副本。
 boolean equals(Object obj)
          两个消息格式对象之间的相等性比较
 StringBuffer format(Object[] arguments, StringBuffer result, FieldPosition pos)
          格式化一个对象数组,并将 MessageFormat 的模式添加到所提供的 StringBuffer,用格式化后的对象替换格式元素。
 StringBuffer format(Object arguments, StringBuffer result, FieldPosition pos)
          格式化一个对象数组,并将 MessageFormat 的模式添加到所提供的 StringBuffer,用格式化后的对象替换格式元素。
static String format(String pattern, Object... arguments)
          创建具有给定模式的 MessageFormat,并用它来格式化给定的参数。
 AttributedCharacterIterator formatToCharacterIterator(Object arguments)
          格式化一个对象数组,并将它们插入 MessageFormat 的模式中,生成一个 AttributedCharacterIterator
 Format[] getFormats()
          获取用于以前所设置的模式字符串中格式元素的格式。
 Format[] getFormatsByArgumentIndex()
          获取传递给 format 方法或从 parse 方法返回的值的格式。
 Locale getLocale()
          获取创建或比较子格式时所使用的语言环境。
 int hashCode()
          生成此消息格式对象的哈希码。
 Object[] parse(String source)
          从给定字符串的开始位置解析文本,以生成一个对象数组。
 Object[] parse(String source, ParsePosition pos)
          解析字符串。
 Object parseObject(String source, ParsePosition pos)
          解析字符串文本,生成一个对象数组。
 void setFormat(int formatElementIndex, Format newFormat)
          使用在以前设置的模式字符串中给定的格式元素索引来设置格式元素使用的格式。
 void setFormatByArgumentIndex(int argumentIndex, Format newFormat)
          设置用于以前所设置的模式字符串中格式元素的格式,其中以前的模式字符串是用给定的参数索引设置的。
 void setFormats(Format[] newFormats)
          设置用于以前所设置的模式字符串中格式元素的格式。
 void setFormatsByArgumentIndex(Format[] newFormats)
          设置传递给 format 方法或从 parse 方法返回的值使用的格式。
 void setLocale(Locale locale)
          设置创建或比较子格式时要使用的语言环境。
 String toPattern()
          返回表示消息格式当前状态的模式。
 
从类 java.text.Format 继承的方法
format, parseObject
 
从类 java.lang.Object 继承的方法
finalize, getClass, notify, notifyAll, toString, wait, wait, wait
 

构造方法详细信息

MessageFormat

public MessageFormat(String pattern)
构造默认语言环境和指定模式的 MessageFormat。构造方法首先设置语言环境,然后解析模式,并为其包含的格式元素创建子格式列表。在类描述中指定了模式及其解释。

参数:
pattern - 此消息格式的模式
抛出:
IllegalArgumentException - 如果模式无效

MessageFormat

public MessageFormat(String pattern,
                     Locale locale)
构造指定语言环境和模式的 MessageFormat。构造方法首先设置语言环境,然后解析模式,并为其包含的格式元素创建子格式列表。在类描述中指定了模式及其解释。

参数:
pattern - 此消息格式的模式
locale - 此消息格式的语言环境
抛出:
IllegalArgumentException - 如果模式无效
从以下版本开始:
1.4
方法详细信息

setLocale

public void setLocale(Locale locale)
设置创建或比较子格式时要使用的语言环境。 这将影响对下面方法的后续调用 不影响已经创建的子格式。

参数:
locale - 创建或比较子格式时所使用的语言环境

getLocale

public Locale getLocale()
获取创建或比较子格式时所使用的语言环境。

返回:
创建或比较子格式时所使用的语言环境

applyPattern

public void applyPattern(String pattern)
设置此消息格式所使用的模式。此方法对模式进行解析,并为其所包含的格式元素创建子格式列表。在类描述中指定了模式及其解释。

参数:
pattern - 此消息格式的模式
抛出:
IllegalArgumentException - 如果模式无效

toPattern

public String toPattern()
返回表示消息格式当前状态的模式。字符串是从内部信息创建的,因此不需要与以前应用的模式相等。

返回:
表示消息格式当前状态的模式

setFormatsByArgumentIndex

public void setFormatsByArgumentIndex(Format[] newFormats)
设置传递给 format 方法或从 parse 方法返回的值使用的格式。newFormats 中元素的索引对应于以前设置的模式字符串中使用的参数索引。因此,newFormats 中的格式顺序对应于传递给 format 方法的 arguments 数组或从 parse 方法返回的结果数组中的元素顺序。

如果一个参数索引用于模式字符串中的多个格式元素,那么对应的新的格式将用于所有这样的格式元素。如果参数索引不用于模式字符串的任何一个格式元素,那么对应的新的格式将被忽略。如果提供的格式少于所需的格式,那么只替换其参数索引小于 newFormats.length 的格式。

参数:
newFormats - 要使用的新格式
抛出:
NullPointerException - 如果 newFormats 为 null
从以下版本开始:
1.4

setFormats

public void setFormats(Format[] newFormats)
设置用于以前所设置的模式字符串中格式元素的格式。newFormats 中的格式顺序对应于模式字符串中的格式元素的顺序。

如果提供的格式多于模式字符串所需的格式,那么剩余的格式将被忽略。如果提供的格式少于所需的格式,那么只替换前 newFormats.length 个格式。

由于在本地化期间,模式字符串中的格式元素顺序经常发生变化,因此最好使用 setFormatsByArgumentIndex 方法,此方法假定格式顺序对应于传递给 format 方法或从 parse 方法返回的结果数组的 arguments 数组中的元素顺序。

参数:
newFormats - 要使用的新格式
抛出:
NullPointerException - 如果 newFormats 为 null

setFormatByArgumentIndex

public void setFormatByArgumentIndex(int argumentIndex,
                                     Format newFormat)
设置用于以前所设置的模式字符串中格式元素的格式,其中以前的模式字符串是用给定的参数索引设置的。参数索引是格式元素定义的一部分,它表示传递给 format 方法或从 parse 方法返回的结果数组的 arguments 数组的索引。

如果参数索引用于模式字符串中的多个格式元素,那么新的格式将用于所有这样的格式元素。如果参数索引没有用于模式字符串的任何格式元素,那么新的格式将被忽略。

参数:
argumentIndex - 要用于新的格式的参数索引
newFormat - 要使用的新格式
从以下版本开始:
1.4

setFormat

public void setFormat(int formatElementIndex,
                      Format newFormat)
使用在以前设置的模式字符串中给定的格式元素索引来设置格式元素使用的格式。格式元素索引是从模式字符串起始位置开始计数的、从 0 开始的数字。

由于在本地化期间,模式字符串中的格式元素的顺序经常发生变化,因此最好使用 setFormatByArgumentIndex 方法,此方法根据它们所指定的参数索引来访问格式元素。

参数:
formatElementIndex - 模式中的格式元素的索引
newFormat - 要用于指定格式元素的格式
抛出:
ArrayIndexOutOfBoundsException - 如果 formatElementIndex 等于或大于模式字符串中格式元素的个数

getFormatsByArgumentIndex

public Format[] getFormatsByArgumentIndex()
获取传递给 format 方法或从 parse 方法返回的值的格式。返回的数组中的元素的索引对应于以前设置模式字符串中所使用的参数索引。因此,返回的数组中的格式顺序对应于传递给 format 方法或从 parse 方法返回的 arguments 数组中的元素顺序。

如果一个参数索引用于模式字符串中的多个格式元素,那么在数组中将返回用于最后一个这样的元素的格式。如果参数索引不用于模式字符串中的任何一个格式元素,那么在数组中将返回 null。

返回:
用于模式中参数的格式
从以下版本开始:
1.4

getFormats

public Format[] getFormats()
获取用于以前所设置的模式字符串中格式元素的格式。返回的数组中的格式顺序对应于模式字符串中的格式元素顺序。

由于在本地化期间,模式字符串中的格式元素的顺序经常发生变化,因此最好使用 getFormatsByArgumentIndex 方法,此方法假定格式的顺序对应于传递给 format 方法的 arguments 数组或从 parse 方法返回的结果数组中的元素顺序。

返回:
用于模式中格式元素的格式

format

public final StringBuffer format(Object[] arguments,
                                 StringBuffer result,
                                 FieldPosition pos)
格式化一个对象数组,并将 MessageFormat 的模式添加到所提供的 StringBuffer,用格式化后的对象替换格式元素。

替换个别格式元素的文本从格式元素和位于格式元素参数索引处的 arguments 元素的当前子格式中派生出来,如下表中第一个匹配行所示。如果 argumentsnull,或者元素的个数少于 argumentIndex+1,则参数是不可用的

子格式 参数 格式化文本
所有 不可用 "{" + argumentIndex + "}"
所有 null "null"
instanceof ChoiceFormat 所有 subformat.format(argument).indexOf('{') >= 0 ?
(new MessageFormat(subformat.format(argument), getLocale())).format(argument) : subformat.format(argument)
!= null 所有 subformat.format(argument)
null instanceof Number NumberFormat.getInstance(getLocale()).format(argument)
null instanceof Date DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument)
null instanceof String argument
null 所有 argument.toString()

如果 pos 不为 null,且引用 Field.ARGUMENT,那么将返回第一个格式化字符串的位置。

参数:
arguments - 要被格式化和替换的对象数组。
result - 添加文本的位置。
pos - 输入时:如果需要,是一个对齐字段。输出时:为对齐字段的偏移量。
抛出:
IllegalArgumentException - 如果 arguments 数组中的参数不是使用该参数的格式元素期望的类型。

format

public static String format(String pattern,
                            Object... arguments)
创建具有给定模式的 MessageFormat,并用它来格式化给定的参数。这等效于
(new MessageFormat(pattern)).format(arguments, new StringBuffer(), null).toString()

抛出:
IllegalArgumentException - 如果模式无效,或者 arguments 数组中的参数不是使用该参数的格式元素期望的类型。

format

public final StringBuffer format(Object arguments,
                                 StringBuffer result,
                                 FieldPosition pos)
格式化一个对象数组,并将 MessageFormat 的模式添加到所提供的 StringBuffer,用格式化后的对象替换格式元素。这等效于
format((Object[]) arguments, result, pos)

指定者:
Format 中的 format
参数:
arguments - 要被格式化和替换的对象数组。
result - 添加文本的位置。
pos - 输入时:如果需要,是一个对齐字段。输出时:为对齐字段的偏移量。
返回:
添加了格式化文本并作为 toAppendTo 传入的字符串缓冲区
抛出:
IllegalArgumentException - 如果 arguments 数组中的参数不是使用该参数的格式元素期望的类型。

formatToCharacterIterator

public AttributedCharacterIterator formatToCharacterIterator(Object arguments)
格式化一个对象数组,并将它们插入 MessageFormat 的模式中,生成一个 AttributedCharacterIterator。可以使用返回的 AttributedCharacterIterator 来生成得到的字符串,以及确定关于得到字符串的信息。

返回的 AttributedCharacterIterator 的文本与以下语句返回的结果相同

format(arguments, new StringBuffer(), null).toString()

此外,AttributedCharacterIterator 至少包含一些属性,指示从 arguments 数组的某个参数生成文本的位置。这些属性的键是 MessageFormat.Field 类型的,其值是 Integer 对象,指示参数的 arguments 数组中的索引,其中文本是从此索引生成的。

MessageFormat 所使用的底层 Format 实例的属性/值也将存放在得到的 AttributedCharacterIterator 中。这不仅允许查找参数被存放在得到的 String 中的位置,而且允许查找它依次包含哪些字段。

覆盖:
Format 中的 formatToCharacterIterator
参数:
arguments - 要被格式化和替换的对象数组。
返回:
描述格式化后的值的 AttributedCharacterIterator。
抛出:
NullPointerException - 如果 arguments 为 null。
IllegalArgumentException - 如果 arguments 数组中的参数不是使用该参数的格式元素期望的类型。
从以下版本开始:
1.4

parse

public Object[] parse(String source,
                      ParsePosition pos)
解析字符串。

警告:在许多情况下解析可能失败。例如:

当解析失败时,使用 ParsePosition.getErrorIndex() 来查找字符串的哪个位置导致了解析失败。返回的错误索引是要用来与字符串比较的子模式的起始偏移量。例如,如果解析的字符串 "AAA {0} BBB" 与模式 "AAD {0} BBB" 进行比较,则错误索引为 0。当发生错误时,对此方法的调用将返回 null。如果源为 null,则返回一个空数组。


parse

public Object[] parse(String source)
               throws ParseException
从给定字符串的开始位置解析文本,以生成一个对象数组。此方法不可以使用给定字符串的全部文本。

有关消息解析的更多信息,请参阅 parse(String, ParsePosition) 方法。

参数:
source - 必须解析其开头的 String
返回:
从字符串进行解析的 Object 数组。
抛出:
ParseException - 如果无法解析指定字符串的开头。

parseObject

public Object parseObject(String source,
                          ParsePosition pos)
解析字符串文本,生成一个对象数组。

此方法试图解析从 pos 给定的索引处开始的文本。如果解析成功,则将 pos 的索引更新到所解析的最后一个字符后面的索引(不必对直到字符串结尾的所有字符进行解析),并返回解析后的对象数组。更新的 pos 可以用来指示下次调用此方法的起始点。如果发生错误,则不更改 pos 的索引,并将 pos 的错误索引设置为发生错误处的字符索引,并且返回 null。

有关消息解析的更多信息,请参阅 parse(String, ParsePosition) 方法。

指定者:
Format 中的 parseObject
参数:
source - 应该解析其中一部分的 String
pos - 具有以上所述的索引和错误索引信息的 ParsePosition 对象。
返回:
从字符串进行解析的 Object 数组。如果发生错误,则返回 null。
抛出:
NullPointerException - 如果 pos 为 null。

clone

public Object clone()
创建并返回此对象的一个副本。

覆盖:
Format 中的 clone
返回:
此实例的一个副本。
另请参见:
Cloneable

equals

public boolean equals(Object obj)
两个消息格式对象之间的相等性比较

覆盖:
Object 中的 equals
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false
另请参见:
Object.hashCode(), Hashtable

hashCode

public int hashCode()
生成此消息格式对象的哈希码。

覆盖:
Object 中的 hashCode
返回:
此对象的一个哈希码值。
另请参见:
Object.equals(java.lang.Object), Hashtable

JavaTM Platform
Standard Ed. 6

提交错误或意见
有关更多的 API 参考资料和开发人员文档,请参阅 Java SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。

版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策