`
huibin
  • 浏览: 739827 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

java.text.MessageFormat 介绍

    博客分类:
  • JAVA
阅读更多
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, new DecimalFormatSymbols(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, 序列化表格

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics