- 所有已实现的接口:
-
Serializable
,Cloneable
MessageFormat
提供了一种以语言中立的方式生成连接消息的方法。使用它来构造显示给最终用户的消息。
MessageFormat
接受一组对象,对它们进行格式化,然后将格式化后的字符串插入到模式中的适当位置。
注意: MessageFormat
与其他 Format
类不同,您使用其构造函数之一创建 MessageFormat
对象(而不是使用 getInstance
风格的工厂方法)。工厂方法是不必要的,因为 MessageFormat
本身不实现特定于区域设置的行为。任何特定于区域设置的行为由您提供的模式以及用于插入参数的子格式定义。
模式及其解释
MessageFormat
使用以下形式的模式:
MessageFormatPattern: String MessageFormatPattern FormatElement String FormatElement: { ArgumentIndex } { ArgumentIndex , FormatType } { ArgumentIndex , FormatType , FormatStyle } FormatType: 其中之一 number date time choice FormatStyle: short medium long full integer currency percent SubformatPattern
在一个 String 中,一对单引号可以用来引用除单引号之外的任意字符。例如,模式字符串 "'{0}'"
表示字符串 "{0}"
,而不是一个 FormatElement。单引号本身必须通过双单引号 ''
来表示。例如,模式字符串 "'{''}'"
被解释为一个序列 '{
(引号开始和左花括号),''
(一个单引号),和 }'
(右花括号和引号结束),而不是 '{'
和 '}'
(引号的左花括号和右花括号):表示字符串 "{'}"
,而不是 "{}"
。
SubformatPattern 由其对应的子格式解释,并应用于依赖于子格式的模式规则。例如,模式字符串 "{1,number,$'#',##}"
(带有下划线的 SubformatPattern)将生成一个带有引号的数值格式,结果可能如下: "$#31,45"
。有关详细信息,请参阅每个 Format
子类的文档。
任何未匹配的引号将被视为在给定模式的末尾关闭。例如,模式字符串 "'{0}"
将被视为模式 "'{0}'"
。
在未引用的模式中的任何花括号必须是平衡的。例如,"ab {0} de"
和 "ab '}' de"
是有效模式,但 "ab {0'}' de"
,"ab } de"
和 "''{''"
不是。
- 警告:
-
遗憾的是,在消息格式模式中使用引号的规则有时会令人感到困惑。特别是,对于本地化人员来说,是否需要将单引号加倍并不总是明显的。确保向本地化人员介绍这些规则,并告诉他们(例如,通过在资源包源文件中使用注释)哪些字符串将由
MessageFormat
处理。请注意,本地化人员可能需要在原始版本中没有的地方在翻译后的字符串中使用单引号。
ArgumentIndex 值是使用数字 '0'
到 '9'
编写的非负整数,表示传递给 format
方法的 arguments
数组中的索引,或者由 parse
方法返回的结果数组中的索引。
FormatType 和 FormatStyle 值用于创建格式元素的 Format
实例。以下表显示这些值如何映射到 Format
实例。表中未显示的组合是非法的。 SubformatPattern 必须是所使用的 Format
子类的有效模式字符串。
使用信息
以下是一些使用示例。在真实的国际化程序中,消息格式模式和其他静态字符串当然将从资源包中获取。其他参数将在运行时动态确定。
第一个示例使用静态方法 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 = {Long.valueOf(fileCount), diskName}; MessageFormat form = new MessageFormat( "磁盘 \"{1}\" 包含 {0} 个文件。"); System.out.println(form.format(testArgs));
fileCount
:
磁盘 "MyDisk" 包含 0 个文件。 磁盘 "MyDisk" 包含 1 个文件。 磁盘 "MyDisk" 包含 1,273 个文件。
对于更复杂的模式,您可以使用 ChoiceFormat
来生成正确的单数和复数形式:
不同值的输出为MessageFormat form = new MessageFormat("磁盘 \"{1}\" 包含 {0}."); double[] filelimits = {0,1,2}; String[] filepart = {"没有文件","一个文件","{0,number} 个文件"}; ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart); form.setFormatByArgumentIndex(0, fileform); int fileCount = 1273; String diskName = "MyDisk"; Object[] testArgs = {Long.valueOf(fileCount), diskName}; System.out.println(form.format(testArgs));
fileCount
:
磁盘 "MyDisk" 包含没有文件。 磁盘 "MyDisk" 包含一个文件。 磁盘 "MyDisk" 包含 1,273 个文件。
您可以像上面的示例那样通过编程方式创建 ChoiceFormat
,也可以使用模式。有关更多信息,请参阅 ChoiceFormat
。
form.applyPattern( "有{0,choice,0#没有文件|1#一个文件|1< {0,number,integer} 个文件}.");
注意: 如上所示,在 MessageFormat
中由 ChoiceFormat
生成的字符串被视为特殊;'{' 的出现用于指示子格式,并导致递归。如果您通过编程方式创建 MessageFormat
和 ChoiceFormat
(而不是使用字符串模式),请小心不要生成递归自身的格式,这将导致无限循环。
当一个参数在字符串中被多次解析时,最后一次匹配将是解析的最终结果。例如,
MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}"); Object[] objs = {Double.valueOf(3.1415)}; String result = mf.format( objs ); // 现在 result 等于 "3.14, 3.1" objs = mf.parse(result, new ParsePosition(0)); // objs 现在等于 {Double.valueOf(3.1)}
同样,使用包含同一参数多次出现的模式进行解析的 MessageFormat
对象将返回最后一次匹配。例如,
MessageFormat mf = new MessageFormat("{0}, {0}, {0}"); String forParsing = "x, y, z"; Object[] objs = mf.parse(forParsing, new ParsePosition(0)); // objs 现在等于 {new String("z")}
同步
消息格式不是同步的。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,必须在外部进行同步。
- 自 JDK 版本:
- 1.1
- 参见:
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
定义了在从MessageFormat.formatToCharacterIterator
返回的AttributedCharacterIterator
中用作属性键的常量。 -
Constructor Summary
ConstructorDescriptionMessageFormat
(String pattern) 为默认的FORMAT
区域设置和指定模式构造了一个 MessageFormat。MessageFormat
(String pattern, Locale locale) 为指定的区域设置和模式构造了一个 MessageFormat。 -
Method Summary
Modifier and TypeMethodDescriptionvoid
applyPattern
(String pattern) 设置此消息格式使用的模式。clone()
创建并返回此对象的副本。boolean
两个消息格式对象之间的相等比较。final StringBuffer
format
(Object[] arguments, StringBuffer result, FieldPosition pos) 格式化对象数组并将MessageFormat
的模式附加到提供的StringBuffer
中,其中格式元素由格式化后的对象替换。final StringBuffer
format
(Object arguments, StringBuffer result, FieldPosition pos) 格式化对象数组并将MessageFormat
的模式附加到提供的StringBuffer
中,其中格式元素由格式化后的对象替换。static String
使用给定的模式创建一个 MessageFormat,并用它来格式化给定的参数。formatToCharacterIterator
(Object arguments) 格式化对象数组并将它们插入到MessageFormat
的模式中,生成一个AttributedCharacterIterator
。Format[]
获取先前设置的模式字符串中格式元素的格式。Format[]
获取传递给format
方法或从parse
方法返回的值所使用的格式。获取在创建或比较子格式时使用的区域设置。int
hashCode()
为消息格式对象生成哈希码。Object[]
从给定字符串的开头解析文本以生成对象数组。Object[]
parse
(String source, ParsePosition pos) 解析字符串。parseObject
(String source, ParsePosition pos) 从字符串中解析文本以生成对象数组。void
设置用于先前设置的模式字符串中具有给定格式元素索引的格式。void
setFormatByArgumentIndex
(int argumentIndex, Format newFormat) 设置用于先前设置的模式字符串中使用给定参数索引的格式。void
setFormats
(Format[] newFormats) 设置用于先前设置的模式字符串中格式元素的格式。void
setFormatsByArgumentIndex
(Format[] newFormats) 设置用于传递给format
方法或从parse
方法返回的值所使用的格式。void
设置在创建或比较子格式时使用的区域设置。返回表示消息格式当前状态的模式。Methods declared in class java.text.Format
format, parseObject
-
Constructor Details
-
MessageFormat
- 参数:
-
pattern
- 此消息格式的模式 - 抛出:
-
IllegalArgumentException
- 如果模式无效 -
NullPointerException
- 如果pattern
为null
-
MessageFormat
为指定的区域设置和模式构造了一个 MessageFormat。构造函数首先设置区域设置,然后解析模式并为其中包含的格式元素创建子格式列表。模式及其解释在类描述中指定。- 实现要求:
-
默认实现在创建
MessageFormat
对象期间或稍后由使用具有空区域设置的MessageFormat
实例调用format()
时抛出NullPointerException
,并且实现使用依赖于区域设置的子格式。 - 参数:
-
pattern
- 此消息格式的模式 -
locale
- 此消息格式的区域设置 - 抛出:
-
IllegalArgumentException
- 如果模式无效 -
NullPointerException
- 如果pattern
或locale
为null
,并且实现使用依赖于区域设置的子格式。 - 自 JDK 版本:
- 1.4
-
-
Method Details
-
setLocale
设置在创建或比较子格式时使用的区域设置。这会影响后续调用- 到
applyPattern
和toPattern
方法,如果格式元素指定格式类型,因此在applyPattern
方法中创建子格式,以及 - 到
format
和formatToCharacterIterator
方法,如果格式元素不指定格式类型,因此在格式化方法中创建子格式。
- 参数:
-
locale
- 创建或比较子格式时要使用的区域设置
- 到
-
getLocale
获取在创建或比较子格式时使用的区域设置。- 返回:
- 创建或比较子格式时使用的区域设置
-
applyPattern
设置此消息格式使用的模式。该方法解析模式并为其中包含的格式元素创建子格式列表。模式及其解释在类描述中指定。- 参数:
-
pattern
- 此消息格式的模式 - 抛出:
-
IllegalArgumentException
- 如果模式无效 -
NullPointerException
- 如果pattern
为null
-
toPattern
返回表示消息格式当前状态的模式。该字符串是从内部信息构造的,因此不一定等于先前应用的模式。- 返回:
- 表示消息格式当前状态的模式
-
setFormatsByArgumentIndex
设置用于传递给format
方法或从parse
方法返回的值所使用的格式。newFormats
中元素的索引对应于先前设置的模式字符串中使用的参数索引。因此,newFormats
中的格式顺序对应于传递给format
方法的arguments
数组中的元素顺序,或者由parse
方法返回的结果数组的顺序。如果一个参数索引用于模式字符串中的多个格式元素,则所有这些格式元素都使用相应的新格式。如果参数索引未用于模式字符串中的任何格式元素,则忽略相应的新格式。如果提供的格式比所需的少,则只替换小于
newFormats.length
的参数索引的格式。- 参数:
-
newFormats
- 要使用的新格式 - 抛出:
-
NullPointerException
- 如果newFormats
为 null - 自 JDK 版本:
- 1.4
-
setFormats
设置用于先前设置的模式字符串中格式元素的格式。newFormats
中的格式顺序对应于模式字符串中格式元素的顺序。如果提供的格式比模式字符串所需的多,则忽略剩余的格式。如果提供的格式比所需的少,则只替换前
newFormats.length
个格式。由于模式字符串中格式元素的顺序在本地化过程中经常发生变化,因此通常最好使用
setFormatsByArgumentIndex
方法,该方法假定格式的顺序与传递给format
方法的arguments
数组的顺序相对应,或者与parse
方法返回的结果数组的顺序相对应。- 参数:
-
newFormats
- 要使用的新格式 - 抛出:
-
NullPointerException
- 如果newFormats
为 null
-
setFormatByArgumentIndex
设置用于先前设置的模式字符串中使用给定参数索引的格式。参数索引是格式元素定义的一部分,表示传递给format
方法的arguments
数组中的索引,或者由parse
方法返回的结果数组中的索引。如果参数索引用于模式字符串中的多个格式元素,则所有这些格式元素都使用新格式。如果参数索引未用于模式字符串中的任何格式元素,则忽略新格式。
- 参数:
-
argumentIndex
- 要使用新格式的参数索引 -
newFormat
- 要使用的新格式 - 自1.4版本起:
- 1.4
-
setFormat
设置要在先前设置的模式字符串中给定格式元素索引处使用的格式。格式元素索引是从模式字符串的开头开始计数的基于零的格式元素编号。由于模式字符串中格式元素的顺序在本地化过程中经常发生变化,通常最好使用
setFormatByArgumentIndex
方法,该方法根据它们指定的参数索引访问格式元素。- 参数:
-
formatElementIndex
- 模式中格式元素的索引 -
newFormat
- 用于指定格式元素的格式 - 抛出:
-
ArrayIndexOutOfBoundsException
- 如果formatElementIndex
等于或大于模式字符串中的格式元素数量
-
getFormatsByArgumentIndex
获取传递给format
方法或从parse
方法返回的值所使用的格式。返回数组中的元素索引对应于先前设置的模式字符串中使用的参数索引。因此,返回数组中的格式顺序与传递给format
方法的arguments
数组中的元素顺序或由parse
方法返回的结果数组中的元素顺序相对应。如果一个参数索引用于模式字符串中的多个格式元素,则返回数组中将返回最后一个这样的格式元素使用的格式。如果参数索引未用于模式字符串中的任何格式元素,则返回数组中将返回null。
- 返回:
- 模式中使用的格式
- 自1.4版本起:
- 1.4
-
getFormats
获取先前设置的模式字符串中使用的格式元素的格式。返回数组中的格式顺序与模式字符串中的格式元素顺序相对应。由于模式字符串中格式元素的顺序在本地化过程中经常发生变化,通常最好使用
getFormatsByArgumentIndex
方法,该方法假定格式的顺序与传递给format
方法的arguments
数组中的元素顺序或由parse
方法返回的结果数组中的元素顺序相对应。- 返回:
- 模式中使用的格式元素的格式
-
format
格式化对象数组并将MessageFormat
的模式附加到提供的StringBuffer
中,其中格式元素由格式化后的对象替换。替换为各个格式元素的文本源自格式元素的当前子格式和由表格的第一行中的第一个匹配行指示的格式元素的参数索引处的
arguments
元素。如果arguments
为null
或少于argumentIndex+1个元素,则参数为不可用。子格式 参数 格式化文本 任意 不可用 "{" + argumentIndex + "}"
null
"null"
ChoiceFormat的实例
任意 subformat.format(argument).indexOf('{') >= 0 ?
(new MessageFormat(subformat.format(argument), getLocale())).format(argument) : subformat.format(argument)!= null
任意 subformat.format(argument)
null
Number的实例
NumberFormat.getInstance(getLocale()).format(argument)
Date的实例
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument)
String的实例
argument
任意 argument.toString()
如果
pos
非空,并且引用Field.ARGUMENT
,将返回第一个格式化字符串的位置。- 参数:
-
arguments
- 要格式化和替换的对象数组 -
result
- 要附加文本的位置 -
pos
- 跟踪输出字符串中第一个替换参数的位置 - 返回:
-
作为
result
传入的字符串缓冲区,附加了格式化的文本 - 抛出:
-
IllegalArgumentException
- 如果arguments
数组中的参数不是格式元素所期望的类型 -
NullPointerException
- 如果result
为null
,或者调用此方法的MessageFormat
实例的区域设置为null,并且实现使用区域设置相关的子格式。
-
format
使用给定的模式创建一个MessageFormat,并使用它来格式化给定的参数。这等效于(new
MessageFormat
(pattern)).format
(arguments, new StringBuffer(), null).toString()- 参数:
-
pattern
- 模式字符串 -
arguments
- 要格式化的对象 - 返回:
- 格式化后的字符串
- 抛出:
-
IllegalArgumentException
- 如果模式无效,或者arguments
数组中的参数不是格式元素所期望的类型 -
NullPointerException
- 如果pattern
为null
-
format
格式化对象数组并将MessageFormat
的模式附加到提供的StringBuffer
中,其中格式元素由格式化后的对象替换。这等效于format
((Object[]) arguments, result, pos)- 在类中指定:
-
format
在类Format
中 - 参数:
-
arguments
- 要格式化和替换的对象数组 -
result
- 要附加文本的位置 -
pos
- 跟踪输出字符串中第一个替换参数的位置 - 返回:
-
作为
toAppendTo
传入的字符串缓冲区,附加了格式化的文本 - 抛出:
-
IllegalArgumentException
- 如果arguments
数组中的参数不是格式元素所期望的类型 -
NullPointerException
- 如果result
为null
,或者调用此方法的MessageFormat
实例的区域设置为null,并且实现使用区域设置相关的子格式。
-
formatToCharacterIterator
格式化对象数组并将它们插入到MessageFormat
的模式中,生成一个AttributedCharacterIterator
。您可以使用返回的AttributedCharacterIterator
来构建生成的字符串,以及确定有关生成的字符串的信息。返回的
AttributedCharacterIterator
的文本与以下内容相同format
(arguments, new StringBuffer(), null).toString()此外,
AttributedCharacterIterator
包含至少指示文本是从arguments
数组中的参数生成的位置的属性。这些属性的键是MessageFormat.Field
类型,它们的值是Integer
对象,指示生成文本的参数在arguments
数组中的索引。MessageFormat
使用的底层Format
实例的属性/值也将放置在生成的AttributedCharacterIterator
中。这使您不仅可以找到参数在生成的字符串中的位置,还可以找到它包含的字段。- 覆盖:
-
formatToCharacterIterator
在类Format
- 参数:
-
arguments
- 要格式化和替换的对象数组。 - 返回:
- 描述格式化值的AttributedCharacterIterator。
- 抛出:
-
NullPointerException
- 如果arguments
为null。 -
IllegalArgumentException
- 如果arguments
数组中的参数不是格式元素所期望的类型。 - 自:
- 1.4
-
parse
解析字符串。注意事项:解析可能在许多情况下失败。例如:
- 如果一个参数不在模式中出现。
- 如果参数的格式丢失信息,例如在选择格式中,一个大数字格式为"many"。
- 尚未处理递归(其中替换的字符串包含{n}引用)。
- 如果解析的某部分存在歧义,则不会始终找到匹配项(或正确的匹配项)。例如,如果将模式"{1},{2}"与字符串参数{"a,b", "c"}一起使用,则格式化为"a,b,c"。当解析结果时,将返回{"a", "b,c"}。
- 如果单个参数在字符串中被解析多次,则后续解析将获胜。
- 参数:
-
source
- 要解析的字符串 -
pos
- 解析位置 - 返回:
- 解析后的对象数组
- 抛出:
-
NullPointerException
- 如果pos
为非null的source
字符串。
-
parse
从给定字符串的开头解析文本以生成对象数组。该方法可能不使用给定字符串的全部文本。有关消息解析的更多信息,请参阅
parse(String, ParsePosition)
方法。- 参数:
-
source
- 应该解析其开头的String
- 返回:
-
从字符串解析的
Object
数组 - 抛出:
-
ParseException
- 如果无法解析指定字符串的开头。
-
parseObject
从字符串解析文本以生成对象数组。该方法尝试从由
pos
给定的索引开始解析文本。如果解析成功,则pos
的索引将更新为使用的最后一个字符之后的索引(解析不一定使用到字符串末尾的所有字符),并返回解析的对象数组。更新后的pos
可以用于指示下一次调用此方法的起始点。如果发生错误,则pos
的索引不会更改,pos
的错误索引设置为发生错误的字符的索引,并返回null。有关消息解析的更多信息,请参阅
parse(String, ParsePosition)
方法。- 指定者:
-
parseObject
在类Format
- 参数:
-
source
- 应解析其中一部分的String
-
pos
- 一个ParsePosition
对象,其中包含上述索引和错误索引信息。 - 返回:
-
从字符串解析的
Object
数组。在发生错误时,返回null。 - 抛出:
-
NullPointerException
- 如果pos
为null。
-
clone
创建并返回此对象的副本。 -
equals
两个消息格式对象之间的相等比较 -
hashCode
public int hashCode()为消息格式对象生成哈希码。
-