8.2.15 MessageFormat类
MessageFormat类可以格式化带占位符的模式字符串。它将模式字符串中的占位符对应一系列的格式化对象,最后使用这些格式化对象依次替换相应的占位符,并返回替换后的字符串。
1. 模式字符串的格式
MessageFormat类所使用的模式字符串形式如下:
At {0} on {1}, there was {2} on planet {3}.
其中被花括号括起来的部分就是模式字符串中的占位符。占位符有如下三种格式:
l { ArgumentIndex }
2 { ArgumentIndex , FormatType }
3 { ArgumentIndex , FormatType , FormatStyle }
其中ArgumentIndex表示一个非负整数(由0至9组成的十进制整数),表示格式化对象数组的索引。也就是说,格式化对象数组中的第3个元素对应的占位符是{2}。
FormatType表示占位符的数据类型,可取的值如下:
l number
2 date
3 time
4 choice
FormatStyle表示占位符的显示格式,可取的值如下:
l short
2 medium
3 long
4 full
5 integer
6 currency
7 percent
8 格式化字符串
其中“格式字符串”是用户自定义的表示数值或日期、时间的格式字符串,如“0.00”、“yyyy-MM-dd”等。
如果想限定格式化对象的数据类型,可以使用模式字符串的第二种或第三种形式。如下面的模式字符串所示:
现在的时间是{0, time, long}。到现在为止,我已经编写了{1, number}个程序模块。
在上面的模式字符串中的第一个占位符不仅限定了格式化对象的数据类型为Date类型,而且使用了long模式来输出格式化对象。
在模式字符串中使用单引号(')时应注意以下三点:
l 夹在两个单引号之间的任何字符都按原样输出。如模式字符串“This is a '{0}'”输出的结果为“This is a {0}”。其中“{0}”并未被当作占位符处理,而是按原样输出。
2 如果有奇数个单引号,则最后一个单引号后面的所有模式字符串都按原样输出。如模式字符串“'ab'c{0}e'f{1}”输出的结果是“abcdef{1}”。从输出结果可以看出,“{0}”被替换成了“d”,而“{1}”并未替换,而是按原样输出。
3 如果要在模式字符串中输出单引号,需要使用两个单引号。如模式字符串“This''s a bike.”输出的结果为”This's a bike.“。
2. 使用MessageFormat类格式化模式字符串
为MessageFormat对象指定模式字符串有如下三种方式:
(1)在创建MessageFormat对象时通过MessageFormat类的构造方法指定模式字符串,代码如下:
MessageFormat mf = new MessageFormat("abc{0}ef{1}");
(2)通过MessageFormat类的applyPattern方法指定模式字符串,代码如下:
MessageFormat mf = new MessageFormat("");
mf.applyPattern("abc{0}ef{1}");
(3)通过MessageFormat类的format方法指定模式字符中。format方法除了可以指定模式字符串外,还可以指定与占位符对应的格式化对象,代码如下:
MessageFormat mf = new MessageFormat("");
mf.format("abc{0}ef{1}", "d", "f");
在第二种和第三种方式中,使用applyPattern方法或format方法指定的模式字符串将覆盖以前设置的模式字符串。如果不想在MessageFormat类的构造方法指定模式字符串,可以赋一个空串(MessageFormat类没有无参数的构造方法)。
除此之外,还可以使用如下两种方式为MessageFormat对象指定本地环境:
(1)在创建MessageFormat对象时通过MessageFormat类的构造方法指定本地环境,代码如下:
MessageFormat mf = new MessageFormat("abc{0}ef{1}", Locale.US);
(2)通过MessageFormat类的setLocale方法指定本地环境,代码如下:
MessageFormat mf = new MessageFormat("");
mf.setLocale(Locale.US);
mf.applyPattern("abc{0}ef{1}");
设置MessageFormat对象的本地环境并不是寻找资源文件,而是要根据占位符的第三个参数输出格式化对象,如下面的代码所示:
MessageFormat mf = new MessageFormat("");
mf.setLocale(Locale.US);
// 按着美国英语环境下的长时间格式输出时间
mf.applyPattern("Now is {0, time, long}.");
System.out.println(mf.format(new Object[]{new Date()}));
mf.setLocale(Locale.CHINA);
mf.applyPattern("Now is {0, time, long}.");
// 按着中文环境下的长时间格式输出时间
System.out.println(mf.format(new Object[]{new Date()}));
上面代码将输出如下的结果:
Now is 11:52:26 PM CST.
Now is 下午11时52分53秒.
MessageFormat类使用format方法格式化模式字符串。format方法最常用的一种重载形式如下:
public final String format (Object[] obj);
其中obj是格式化对象数组。如下面的代码所示:
MessageFormat mf = new MessageFormat("");
mf.applyPattern("abc{0}ef{1}");
System.out.println(mf.format(new Object[]{"d", "g"}));
MessageFormat类的format方法还有一个静态重载形式。该重载形式除了指定格式化对象外,还需要指定模式字符串。该重载形式的定义如下:
public static String format(String pattern, Object ... arguments);
下面的代码使用format方法的静态重载形式格式化模式字符串:
MessageFormat.format("abc{0}ef{1}", "d", "f");
format方法的静态重载形式也可以在MessageFormat类的对象实例中使用,这时设置的本地环境将生效,代码如下:
MessageFormat mf = new MessageFormat("");
mf.setLocale(Locale.FRANCE);
mf.format("Now is {0, time, long}.",new Date());