java.lang.Object java.text.Format java.text.MessageFormat
public class MessageFormat
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"
则是无效的。
ArgumentIndex 值是使用数字 '0' 到 '9' 表示的非负整数,它表示传递给 format
方法的 arguments
数组的一个索引,或者表示由 parse
方法返回的结果数组的一个索引。
FormatType 和 FormatStyle 值用来创建格式元素的 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
所生成的字符串要进行特殊处理;'{' 的出现用来指示子格式,并导致递归。如果 MessageFormat
和 ChoiceFormat
都是以编程方式创建的(而不是使用字符串模式),那么要注意不要生成对其自身进行递归的格式,这将导致无限循环。
当一个参数在字符串中被多次解析时,最后的匹配将是解析的最终结果。例如,
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 |
构造方法详细信息 |
---|
public MessageFormat(String pattern)
pattern
- 此消息格式的模式
IllegalArgumentException
- 如果模式无效
public MessageFormat(String pattern, Locale locale)
pattern
- 此消息格式的模式
locale
- 此消息格式的语言环境
IllegalArgumentException
- 如果模式无效
方法详细信息 |
---|
public void setLocale(Locale locale)
applyPattern
和 toPattern
方法的后续调用,如果格式元素指定了格式类型并且因此具有在 applyPattern
方法中创建的子格式,以及 format
和 formatToCharacterIterator
方法的后续调用,如果格式元素未指定格式类型并且因此具有在格式化方法中创建的子格式。
locale
- 创建或比较子格式时所使用的语言环境
public Locale getLocale()
public void applyPattern(String pattern)
pattern
- 此消息格式的模式
IllegalArgumentException
- 如果模式无效
public String toPattern()
public void setFormatsByArgumentIndex(Format[] newFormats)
format
方法或从
parse
方法返回的值使用的格式。
newFormats
中元素的索引对应于以前设置的模式字符串中使用的参数索引。因此,
newFormats
中的格式顺序对应于传递给
format
方法的
arguments
数组或从
parse
方法返回的结果数组中的元素顺序。
如果一个参数索引用于模式字符串中的多个格式元素,那么对应的新的格式将用于所有这样的格式元素。如果参数索引不用于模式字符串的任何一个格式元素,那么对应的新的格式将被忽略。如果提供的格式少于所需的格式,那么只替换其参数索引小于 newFormats.length
的格式。
newFormats
- 要使用的新格式
NullPointerException
- 如果
newFormats
为 null
public void setFormats(Format[] newFormats)
newFormats
中的格式顺序对应于模式字符串中的格式元素的顺序。
如果提供的格式多于模式字符串所需的格式,那么剩余的格式将被忽略。如果提供的格式少于所需的格式,那么只替换前 newFormats.length
个格式。
由于在本地化期间,模式字符串中的格式元素顺序经常发生变化,因此最好使用 setFormatsByArgumentIndex
方法,此方法假定格式顺序对应于传递给 format
方法或从 parse
方法返回的结果数组的 arguments
数组中的元素顺序。
newFormats
- 要使用的新格式
NullPointerException
- 如果
newFormats
为 null
public void setFormatByArgumentIndex(int argumentIndex, Format newFormat)
format
方法或从
parse
方法返回的结果数组的
arguments
数组的索引。
如果参数索引用于模式字符串中的多个格式元素,那么新的格式将用于所有这样的格式元素。如果参数索引没有用于模式字符串的任何格式元素,那么新的格式将被忽略。
argumentIndex
- 要用于新的格式的参数索引
newFormat
- 要使用的新格式
public void setFormat(int formatElementIndex, Format newFormat)
由于在本地化期间,模式字符串中的格式元素的顺序经常发生变化,因此最好使用 setFormatByArgumentIndex
方法,此方法根据它们所指定的参数索引来访问格式元素。
formatElementIndex
- 模式中的格式元素的索引
newFormat
- 要用于指定格式元素的格式
ArrayIndexOutOfBoundsException
- 如果 formatElementIndex 等于或大于模式字符串中格式元素的个数
public Format[] getFormatsByArgumentIndex()
format
方法或从
parse
方法返回的值的格式。返回的数组中的元素的索引对应于以前设置模式字符串中所使用的参数索引。因此,返回的数组中的格式顺序对应于传递给
format
方法或从
parse
方法返回的
arguments
数组中的元素顺序。
如果一个参数索引用于模式字符串中的多个格式元素,那么在数组中将返回用于最后一个这样的元素的格式。如果参数索引不用于模式字符串中的任何一个格式元素,那么在数组中将返回 null。
public Format[] getFormats()
由于在本地化期间,模式字符串中的格式元素的顺序经常发生变化,因此最好使用 getFormatsByArgumentIndex
方法,此方法假定格式的顺序对应于传递给 format
方法的 arguments
数组或从 parse
方法返回的结果数组中的元素顺序。
public final StringBuffer format(Object[] arguments, StringBuffer result, FieldPosition pos)
MessageFormat
的模式添加到所提供的
StringBuffer
,用格式化后的对象替换格式元素。
替换个别格式元素的文本从格式元素和位于格式元素参数索引处的 arguments
元素的当前子格式中派生出来,如下表中第一个匹配行所示。如果 arguments
为 null
,或者元素的个数少于 argumentIndex+1,则参数是不可用的。
子格式 | 参数 | 格式化文本 |
---|---|---|
所有 | 不可用 | "{" + argumentIndex + "}" |
所有 | null |
"null" |
instanceof ChoiceFormat |
所有 | subformat.format(argument).indexOf('{') >= 0 ? |
!= 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
数组中的参数不是使用该参数的格式元素期望的类型。
public static String format(String pattern, Object... arguments)
(new MessageFormat
(pattern)).format
(arguments, new StringBuffer(), null).toString()
IllegalArgumentException
- 如果模式无效,或者
arguments
数组中的参数不是使用该参数的格式元素期望的类型。
public final StringBuffer format(Object arguments, StringBuffer result, FieldPosition pos)
MessageFormat
的模式添加到所提供的
StringBuffer
,用格式化后的对象替换格式元素。这等效于
format
((Object[]) arguments, result, pos)
arguments
- 要被格式化和替换的对象数组。
result
- 添加文本的位置。
pos
- 输入时:如果需要,是一个对齐字段。输出时:为对齐字段的偏移量。
toAppendTo
传入的字符串缓冲区
IllegalArgumentException
- 如果
arguments
数组中的参数不是使用该参数的格式元素期望的类型。
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
- 要被格式化和替换的对象数组。
NullPointerException
- 如果
arguments
为 null。
IllegalArgumentException
- 如果
arguments
数组中的参数不是使用该参数的格式元素期望的类型。
public Object[] parse(String source, ParsePosition pos)
警告:在许多情况下解析可能失败。例如:
public Object[] parse(String source) throws ParseException
有关消息解析的更多信息,请参阅 parse(String, ParsePosition)
方法。
source
- 必须解析其开头的
String
。
Object
数组。
ParseException
- 如果无法解析指定字符串的开头。
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。
public Object clone()
public boolean equals(Object obj)
obj
- 要与之比较的引用对象。
true
;否则返回
false
。
Object.hashCode()
,
Hashtable
public int hashCode()
Object.equals(java.lang.Object)
,
Hashtable