简单的Java程序的国际化
以下参考至李刚. 疯狂Java讲义(第5版) 电子工业出版社
一、Java 国际化的简单说明
Java 程序的国际化就是将程序中的标签、提示等信息放在资源文件中,程序需要支持哪些国家、语言环境,就对应提供相应的资源 文件。资源文件是 key- value 对,每个资源文件中的 key 不变的 但 value 则随不同的国家语言而改变。
二、程序国际化的操作
1.编写资源文件
如编写程序打印hello为例子,中文语言环境下输出“你好”,英文环境下输出"Hey"。即Key=hello,value=“你好"或者"Hey”。
为上面程序提供如下两个文件。第一个文件:mess_ zh_ CN. properties,该文件的内容为:
#资源文件的内容是key-value对
hello=你好!
第二个文件:mess_ en_ US. properties,该文件的内容为:
#资源文件的内容是key-value对
hello=Hey!
文件说明
资源文件的命名可以有如下三种形式。
➢ baseName_ language_ country. properties
➢ baseName_ language. properties
➢ baseName. properties
其中 baseName 是资源文件的基本名,用户可随意指定;而 language 和 country 都不可随意变化,必须是 Java 所支持的语言和国家。(具体支持哪些国家可以百度)
从 Java 9 开始, Java 支持 使用 UTF- 8 字符 集 来 保存 属性 文件,这样在属性文件中就可以直接包含非西欧字符,因此属性文件也不再需要使用 native2ascii 工具进行处理。唯一 要注意的是,属性文件必须显式保存为 UTF- 8 字符集。
可以将文件放入直接项目的src目录下或者类包下。
2.程序示例
首先导入类
导入三个类
import java.util.ResourceBundle;
import java.util.Locale;
import java.text.MessageFormat;
Java 程序的国际化主要通过这三个类完成。
➢ java.util.ResourceBundle:用于加载国家、语言资源包。
➢ java.util.Locale:用于封装特定的国家/区域、语言环境。
➢ java.text.MessageFormat:用于格式化带占位符的字符串。
代码
如
public class InterHello {
public static void main(String[] args) {
//取得系统默认的国家/语言环境
var myLocale=Locale.getDefault(Locale.Category.FORMAT );
//根据指定的国家/语言环境加载文件资源
var bundle=ResourceBundle.getBundle("pakegeA.mess",myLocale);
//打印从资源文件中取得的消息
System.out.println(bundle.getString("hello"));
}
}
其中
ResourceBundle.getBundle(“pakegeA.mess”,myLocale)
将会加载baseName为mess的系列资源文件之一,到底加载其中的哪个资源文件,则取决于myLocale,对于简体中文的 Locale,则加载mess_zh_CN.properties文件。
mess文件如果在项目src的目录下则不用***.mess来加载,此处是将资源文件放入了类的里(包在src目录下),包名是PackageA,与InterHello类放在一起。同理如果放入其他目录也可以用 . 来指明路径。
如图
3.使用MessageFormat 处理包含占位符的字符串
占位符的使用在这里不详细介绍。
需要使用 MessageFormat 类,该类包含一个有用的静态方法。 format( String pattern, Object… values):返回后面的多个参数值填充 前面的 pattern 字符串,其中pattern字符串不是正则表达式,而是一个带占位符的字符串。
将mess_ zh_ CN. properties文件内容修改如下
#资源文件的内容是key-value对
hello=你好! 今天是{0}. 今天天气是 {1}.
代码修改如下
public class InterHello {
public static void main(String[] args) {
//取得系统默认的国家/语言环境
var myLocale=Locale.getDefault(Locale.Category.FORMAT );
//根据指定的国家/语言环境加载文件资源
var bundle=ResourceBundle.getBundle("pakegeA.mess",myLocale);
var msg=bundle.getString("hello");
System.out.println(MessageFormat.format(msg,new Date(),"大雪"));
}
}
中文环境运行结果
4.类文件代替资源文件
除使用属性文件作为资源文件外,java也允许使用类文件代替资源文件,即将所有的key- value对存入class文件,而不是属性文件。使用类文件来代替资源文件必须满足如下条件。
➢该类的类名必须是baseName_ language_ country,这与属性文件的命名相似。
➢ 该类 必须 继承 ListResourceBundle,并重写getContents()方法,该方法返回Object数组,该数组的每一项都是key- value对。下面的类文件可以代替上面的属性文件。
public class messclass_zh_CN extends ListResourceBundle{
//定义资源
private final Object myDate[][]=
{
{"hello","你好! 今天是{0}今天天气是 {1}"}
};
//重写getContents()方法
public Object[][] getContents()
{
//该方法返回资源key-value对
return myDate;
}
}
测试时,将main函数中"pakegeA.mess"改为"pakegeA.messclass"即可。当然也可以使类名与之前的属性文件名相同。
如果系统同时存在资源文件、类文件,系统将以类文件为主,而不会调用资源文件。对于简体中文的 Locale,ResourceBundle搜索资源文件的顺序是:
(1) baseName_ zh_ CN. class
(2) baseName_ zh_ CN. properties
(3) baseName_ zh. class
(4) baseName_ zh. properties
(5) baseName. class
(6) baseName. properties
系统按上面的顺序搜索资源文件,如果前面的文件不存在,才会使用下一个文件。如果一直找不到对应的文件,系统将抛出异常。