国际化的思路
Java 程序的国际化思路是将程序中的标签、提示等信息放在资源文件中,程序需要支持哪些国家、语言环境,就对应提供相应的资源文件。资源文件是 key-value 对,每个资源文件中的 key 是不变的,但 value 则随不同的国家、语言而改变。
Java程序的国际化主要通过如下三个类完成:
- java.util.ResourceBundle:用于加载国家、语言资源包。
- java.util.Locale:用于封装特定的国家/区域、语言环境。
- java.text.MessageFormat:用于格式化带占位符的字符串。
资源文件的内容是很多的 key-value 对,其中 key 是程序使用的部分,而 value 则是程序界面的显式字符串。资源文件的命名可以有如下三种形式:
- baseName_language_contry.properties
- baseName_language.properties
- baseName.properties
baseNaem 是资源文件的基本名,可以随意指定;而 language 和 country 都不可随意变化,必须是Java支持的语言和国家。1
2
3
4
5
6
7
8//返回Java所支持的全部国家和语言的数组
Local[] localList=Locale.getAvailableLocales();
//遍历数组的每个元素,依次获取所支持的国家和语言
for (int i=0;i<localeList.length;i++)
{
System.out.println(localeList[i].getDisplayCountry()+"="+localeList[i].getCountry()+" "+
localeList[i].getDisplayLanguage()+"="+localeList[i].getLanguage());
}
完成国际化的步骤
准备资源文件
为程序提供两个文件:
第一个文件:mess.properties,其内容为:1
2#资源文件的内容是 key-value 对
hello=你好!
第二个文件:mess_en_US.properties,该文件的内容为:1
2#资源文件的内容是 key-value 对
hello=Welcome!
对于包含非西欧字符的资源文件,Java提供了一个工具来处理该文件:native2ascii,这个工具可以在 %JAVA_HOME%/bin 路径下找到,使用该工具的语法格式如下:
1 native2ascii 资源文件 目的资源文件
在命令窗口输入如下命令:1
native2ascii mess.properties mess_zh_CN.properties
上面的命令将生成一个 mess_zh_CN.properties 文件,该文件才是程序需要的资源文件,该文件里面是非西欧字符的 Unicode 编码方式。
进行国际化
1 | //取得系统默认的国家/语言环境 |
注意该代码:1
2//根据指定的国家/语言环境加载资源文件
ResourceBundle bundle=ResourceBundle.getBundle("mess",myLocale);
上面代码将会加载 baseName 为 mess 的系列资源之一,到底加载其中的哪个资源文件,则取决于 myLocale ;对于简体中文的 Locale ,则加载 mess_zh_CN.properties 文件。
使用 MessageFormat 处理包含占位符的字符串
前面程序输出的消息是一个简单信息,如果需要输出的消息中必须包含动态的内容,例如,这些内容必须是从程序中取得的:1
你好,yeeku!今天是 2018-03-12 上午 10:24
上面的输出字符串中,yeeku 是用户的名字,必须动态改变,后面的时间也必须动态改变。在这种情况先,可以使用带占位符的消息。
例如,提供一个 myMess_en_US.properties 文件,该文件内容如下:1
msg=Hello,{0}!Today is {1}.
提供一个 myMess.properties 文件,内容如下:1
msg=你好,{0}! 今天是 {1}。
现在,程序需要为 {0} 和 {1} 两个占位符赋值,此时需要使用 MessageFormat 类,该类包含了一个静态方法:
- format(String pattern,Object… values):返回后面的多个参数值填充前面的 patter 字符串,其中 pattern 是一个带占位符的字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//定义一个 Locale 变量
Locale currentLocale = null;
//如果运行程序指定了两个参数
if(args.length == 2)
{
//使用运行程序的两个参数构造 Locale 实例
currentLocale = new Locale(args[0],args[1]);
}
else
{
//否则直接使用系统默认的 Locale
currentLocale = Locale.getDefault(Locale.Catefory.FORMAT);
}
//根据 Locale 加载语言资源
ResourceBundle bundle = ResourceBundle.getBundle("myMess",currentLocal);
//取得已加载的语言资源文件中的 msg 对应消息
String msg = bundle.getString("msg");
//使用 MessageFormat 为带占位符的字符串传入参数
System.out.println(MessageFormat.format(msg,"yeeku",new Date());
使用类文件代替资源文件
除了使用属性文件作为资源文件外,Java也允许使用类文件代替资源文件,即将所以的 key-value 对存入 class 文件,而不是属性文件。
使用类文件来代替资源文件必须满足以下条件:
- 该类的类名必须是 baseName_language_country,这与属性文件的命名方式相似。
- 该类必须继承 ListResourceBundle,并重写 getContents() 方法,该方法返回 Object数组,该数组的每一项都是 key-value 对。
以下是一个简体中文语言环境的资源文件,可以替代 Mess_zh_CN.properties。当系统同时存在资源文件、类文件时,以类文件为主。
1 | public class Mess_zh_CN extends ListResourceBundle |