如果一个字符串文本中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理。

  例如:

  在2016年1月9日的时候,一场台风导致了500间房屋的摧毁和¥1000000元人民币的损失。

  在上面这句话中,包含了时间、数字和货币等多个与国家化相关的数据,已经用下划线标出,而我们可以使用MessageFormat对这句话中多个数据进行批量处理。

  要想使用MessageFormat进行批量处理,就要使用到占位符,用占位符替换上面的数据(不需要写死的数据或者与国际化相关的数据)。占位符由花括号{}和在花括号中的数字组成,数字代表这是第几个占位符,现在我们对上面的那个示例使用占位符:

  在{0}的时候,一场台风导致了{1}间房屋的摧毁和{2}元人民币的损失。

  经过占位符修改的字符串文本也称为模式字符串,如上面这句话,有了模式字符串后,我们需要一个对象数组来指定每个占位符对应的数据,在数组中的位置就对应着其相同位置的占位符。现在拥有了模式字符串和对象数组后,我们就可以使用MessageFormat对象的format方法,将数组中的数据一一对应到占位符上了。

  占位符由三种书写格式:

  ① {index}:index为0~9之间的数字,对应对象数组中的位置。

  ② {index,formatType}:index为0~9之间的数字,formatType为参数的格式化类型

  ③  {index,formatType,formatStyle}:formatStyle为参数的格式化样式。

有关占位符的使用稍后说明。

注:在创建MessageFormat对象时可以直接将模式字符串以参数传入构造器,也可以直接使用MessageFormat的静态方法format(String pattern , Object …params)只执行一次。

例1:

     String pattern = "在{0}的时候,一场台风导致了{1}间房屋的摧毁和{2}元人民币的损失。";
Object[] params = {new Date(),500,1000000};
MessageFormat mf = new MessageFormat(pattern);
String content = mf.format(params);
System.out.println(content);

上述代码等同于:

     String pattern = "在{0}的时候,一场台风导致了{1}间房屋的摧毁和{2}元人民币的损失。";
Object[] params = {new Date(),500,1000000};
String content = MessageFormat.format(pattern, params);
System.out.println(content);

输出:

  

结果就是:在16-1-9 下午7:56的时候,一场台风导致了500间房屋的摧毁和1,000,000元人民币的损失。

  可以看到在对应的占位符上,我们用对象数组中的内容替代了占位符。但是似乎和最开始我们规定的字符串文本有点不同?

最开始我们规定的文本:

  在2016年1月9日的时候,一场台风导致了500间房屋的摧毁和¥1,000,000元人民币的损失。

例1占位符被替代后的文本:

  在16-1-9 下午7:56的时候,一场台风导致了500间房屋的摧毁和1,000,000元人民币的损失。

  可以看到日期格式和货币格式跟我们规定的不同,而这一点可以想到前一篇博客我们学到的DateFormat和NumberFormat中可以指定日期/时间或货币的输出格式。而这里我们要先了解下占位符:

  占位符有三种书写格式:

  ① {index}:index为0~9之间的数字,对应对象数组中的位置。

  ② {index,formatType}:index为0~9之间的数字,formatType为参数的格式化类型

  ③ {index,formatType,formatStyle}:formatStyle为参数的格式化样式,该样式必须是格式化类型相匹配的合法模式,或表示合法模式的字符串。

  在Java的API关于MessageFormat中,已经定义了formatType和formatStyle能使用的参数有哪些:

  

  通过上图我们就明白了formatType和formatStyle到底能使用哪些值,比如formatType如果我选了“date”,就代表该占位符是一个日期,那么可以指定formatStyle(使用占位符第三种书写方式),也就是DateFormat的日期显示格式;当然也可以不指定(使用占位符第二种书写方式),那么该DateFormat就采用默认(MEDIUM)的日期显示格式。如果formatType选择为“number”也是一样的道理。如果对DateFormat和NumberFormat不熟悉的可以看上一篇博客《国际化之DateFormat、NumberFormat》 。

总结:

  formatType如果使用“date”,那么就是采用DateFormat类的getDateInstance方法获取只关于日期的DateFormat类实例对象,根据formatStyle来获取日期输出格式。

  formatType如果使用“time”,那么就是采用DateFormat类的getTimeInstance方法获取只关于时间的DateFormat类实例对象,根据formatStyle来获取时间输出格式。

  formatType如果使用“number”,如果也指定了formatStyle为“currency”,那么就是调用了NumberFormat的getCurrencyInstance方法获取有关于货币格式的NumberFormat类对象。

  当然通过上图还可以获得很多对象,还有其他类型的格式转换器类,比如SimpleDateFormat等等,具体根据上图和实际情况满足需求即可。

例2:

     String pattern = "在{0,date,long}的时候,一场台风导致了{1}间房屋的摧毁和{2,number,currency}元人民币的损失。";
Object[] params = {new Date(),500,1000000}; String content = MessageFormat.format(pattern, params);
System.out.println(content);

输出:

  

结果就是:在2016年1月9日的时候,一场台风导致了500间房屋的摧毁和¥1,000,000.00元人民币的损失。

  可以看到这就跟我们的最开始定义的字符串文本相同了。

  占位符在框架中是经常被使用到的,当然占位符一般不会在程序代码中被使用,而是在资源文件properties被使用,这是想Struts2这样的框架经常被使用到的,结合前两篇的《国际化之ResourceBundle》,如果模式字符串在properties中使用,那么我们需要通过ResourceBundle通过资源文件的基名获取对象,并使用getString方法获取模式字符串,最后只要使用MessageFormat像上面一样处理就行了。

例3:

  在工程中用一个包来封装一组资源包,该组资源包中默认的资源配置文件基名为“MessageResource”,同时配有中文和英文两个资源配置文件,如下图所示:

  

在默认的资源文件“MessageResource.properties”中定义的内容如下:

  

在中文资源文件“MessageResource_zh.properties”中定义的内容如下:

  

  英文资源文件和默认资源文件中的内容是一样的,这里就不再贴出。

  因为我们将资源文件放在包中,所以基名应该包括包名,这一点在博文《《国际化之ResourceBundle》中已经说明。

在程序中代码如下:

     ResourceBundle bundle = ResourceBundle.getBundle("com.fjdingsd.resource.MessageResource",Locale.CHINA);
String pattern = bundle.getString("message"); //获取模式字符串
Object[] params = {new Date(),500,10000000}; String content = MessageFormat.format(pattern, params);
System.out.println(content);

输出:在16-1-9 下午8:59的时候,一场台风导致了500间房屋的摧毁和10,000,000元人民币的损失。

注意:⑴ 这里占位符对应的地方格式并不友好,这是因为占位符没有使用特定的格式,参见例2。

   ⑵ 在ResourceBundle获取对象中使用到了Locale是以中国的形式,因此最后输出的是中文,如果想以美国作为Locale,那么将会输出英文:

修改代码为:

     ResourceBundle bundle = ResourceBundle.getBundle("com.fjdingsd.resource.MessageResource",Locale.US);
String pattern = bundle.getString("message"); //获取模式字符串
Object[] params = {new Date(),500,10000000}; String content = MessageFormat.format(pattern, params);
System.out.println(content);

输出:On 16-1-9 下午9:03, a typhoon destory 500 houses and caused 10,000,000 of damage.

  看上去似乎很正确,但是在这些英文中出现了中文,而且是在占位符对应的地方,说明我们还未将MessageFormat对象的代表的语言国家环境修改,最终代码如下:

     ResourceBundle bundle = ResourceBundle.getBundle("com.fjdingsd.resource.MessageResource",Locale.US);
String pattern = bundle.getString("message"); //获取模式字符串
Object[] params = {new Date(),500,10000000}; MessageFormat mf = new MessageFormat(pattern, Locale.US);
String content = mf.format(params);
System.out.println(content);

输出:On 1/9/16 9:07 PM, a typhoon destory 500 houses and caused 10,000,000 of damage.

国际化之MessageFormat与占位符的更多相关文章

  1. MessageFormat与占位符使用

    占位符替换,花括号中为索引占位,对应可变参数后面的值 String pattern = "ErrorMessage=This is Error Message : {0},{1}" ...

  2. 使用MessageFormat替换字符中的占位符

    使用String.format可以实现字符串的格式化功能,即将后面参数中的值替换掉format中的%s,%d这些值.但MessageFormat更为强大,不用管传入值是字符串还是数字,使用占位符即可. ...

  3. Java C# C语言中的占位符

    一般拼接一段字符串在编程中是很常见的事,下面简单做个总结: 什么是占位符?占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号. 1.Java中处理方法: package com.amos; ...

  4. Java使用占位符拼接字符串

    大家知道,在C#编程中,可以用占位符来拼接字符串,用起来非常的方便. 特别是需要进行大量的参数拼接的时候,比如: Console.WriteLine(String.Format("该域名{0 ...

  5. Java 占位符

    Java的占位符有两种:% 和 {} String 类对象 只能使用 % 有效. MessageFormat 类对象 只能使用 {} 有效. package demo; import java.tex ...

  6. Java字符串占位符(commons-text)替换(转载)

    Java字符串占位符(commons-text)替换 https://blog.csdn.net/varyall/article/details/83651798 <dependency> ...

  7. Java占位符

    一.背景 在使用java开发的过程中,经常需要使用将字符串拼接到一起(比如,用于日志输出),常用方法如下: 使用+将不同字符串进行拼接 使用StringBuilder 使用String.format ...

  8. Java{0}占位符替换字符串

    Java{0}占位符替换字符串 public class Test { public static void main(String[] args) { System.out.println(Stri ...

  9. java string常用的占位符形式

        自己在这里总结了三种占位符形式:看下面代码即可 String stringFormat  = "lexical error at position %s, encountered % ...

随机推荐

  1. dpkg卸载和安装deb

    今天在linux mint上安装个东西,没有安装完全,但是启动的时候能够启动,为了防止以后出现异常,想把它卸载了,在软件上点卸载,没有反应, 如下图: 没有指定卸载的包源,无奈使用sudo apt-g ...

  2. CMarkup类在VC中的使用

    首先到http://www.firstobject.com/dn_markup.htm上面下载CMarkup类,将CMarkup.cpp和CMarkup.h导入到我们的工程中就可以了.编译可能会出现问 ...

  3. BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )

    先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ---------------------------------------------------------- ...

  4. 深入理解-HashMap

    一.HashMap概述 HashMap 在家族中位置:实现了Map接口,继承AbstractMap类.HashMap 允许key/value 都为null. 二.HashMap存储结构 HashMap ...

  5. 在VC6.0中能不能使用Duilib界面库呢?

    Duilib库的源代码是在vs2010下编译的,一般适用于vs2008及以上的版本开发使用,那么duilib能不能在vc6.0的工程中使用呢?如何在vc6.0中使用duilib库呢? 今天,由于工作要 ...

  6. uva 816 - Abbott&#39;s Revenge(有点困难bfs迷宫称号)

    是典型的bfs,但是,这个问题的目的在于读取条件的困难,而不是简单地推断,需要找到一种方法来读取条件.还需要想办法去推断每一点不能满足条件,继续往下走. #include<cstdio> ...

  7. Android --Vibrator--震动服务

    1.取得震动服务的句柄 vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);或者vibrator = (Vibrator)getAppli ...

  8. Python 第八篇:异常处理、Socket语法、SocketServer实现多并发、进程和线程、线程锁、GIL、Event、信号量、进程间通讯

    本节内容: 异常处理.Socket语法.SocketServer实现多并发.进程和线程.线程锁.GIL.Event.信号量.进程间通讯.生产者消费者模型.队列Queue.multiprocess实例 ...

  9. 07-UIKit(tableview的编辑模式、accessoryView)

    目录: 一.tableview的编辑模式-增删改查 二.不使用继承创建tableview 三.accessoryView辅助视图 回到顶部 一.tableview的编辑模式-增删改查 [1-conta ...

  10. android sdk国内快速更新下载

    Android SDK在线更新镜像服务器 http://www.androiddevtools.cn/ 目前正在使用的是:包含详细的配图流程 http://android-mirror.bugly.q ...