国际化的操作就是指一个程序可以同时适应多门语言,即:如果现在程序的使用者是中国人,则会以中文显示,如果现在程序的使用者是英国人,则会以英文 显示,也就是通过国际化操作,让一个程序适应过个国家的语言,程序根据不同的语言环境找到不同的资源文件,资源文件的内容是以key-value的形式保 存的,所以在读取的时候通过key找到值
如果要想实现java程序的国际化操作必须通过以下三个类完成
java.util.Locale:用于表示一个国家语言类
java.util.ResourceBundle:用于访问资源文件
java.text.MessageFormat:格式化资源文件的占位字符串
Locale表示的是本地,实际上使用的是一个ISO编码的封装类,对于各个国家来说都存在一个唯一的编码,那么这种编码称为ISO编码,使用Locale可以指定好一个具体的国家编码
例如 中国的编码:zh-CN
英国的编码 :en-US
法语的编码:fr-FR
ResourceBundle
此类是专门完成属性文件读取操作的,读取的时候直接指定文件名称即可,(此文件名称一般不需要指定后缀,后缀统一为*.properties)。可以根据Local所指定的区域编码来自动选择所需要的资源文件
public static final ResourceBundle getBundle(String baseName)此方法就是指定要操作的资源文件,此方法找到的是默认的操作系统的语言Locale对象
public static final ResourceBundle getBundle(String baseName,Locale locale)此方法也是指定操作资源文件,并传入Locale对
getString(name)根据key取得value
事例
资源文件命名的时候最好采用单词字母大写的方式完成
定义一个资源文件
message.properties
info=hello
在test类中取得
package com.qn.gj;
import java.util.ResourceBundle;
public class interDemo {
public static void main(String[] args) {
ResourceBundle rb=ResourceBundle.getBundle("message");
String str=rb.getString("info");//根据key值取得value
System.out.println(str);
}
}
结果
java国际化程序的开发
事例
中文: 你好
英文: hello
分别定义不同的资源文件,此时需要定义两个资源文件,在定义资源文件的时候需要指定该资源文件对于的语言编码
中文:message_zh_CN.properties
英文:message_en_US.proerties
定义message_en_US.properties文件
info=hello
定义message_zh_CN.properties文件
info=u4F60u597D
在test类中进行测试
package com.qn.gj;
import java.util.Locale;
import java.util.ResourceBundle;
public class interDemo {
public static void main(String[] args) {
Locale zhLoc=new Locale("zh","CN");//表示中文地区
Locale enLoc=new Locale("en","US");//表示英文地区
//找到中文的属性文件,需要指定中文Locale
ResourceBundle zhrb=ResourceBundle.getBundle("message",zhLoc);
//找到英文的属性文件,需要指定英文Locale
ResourceBundle enrb=ResourceBundle.getBundle("message",enLoc);
String zhStr=zhrb.getString("info");//根据key值取得value
String enStr=enrb.getString("info");//根据key值取得value
System.out.println("中文:"+zhStr);
System.out.println("英文:"+enStr);
}
}
结果
上面的信息读出来了。但是程序开发的时候要注意,对于中文的资源文件,虽然现在可以直接通过中文读取,但是这样做是不可理的应该将其进行Unicode编码,转换为java认识的16进制的,避免一些系统带来的乱码问题
只要是中文就必须进行转码操作
处理动态文本
上面的内容都是固定的,如果设置这样的内容的时候呢?如你好xxx,这时候内容不固定,这时候就要使用占位符了
这个时候就要用到MessageFormat类了
在Format类中还存在数字格式化的Format(NumberFormat)、日期格式化的Format(DateFormat)
占位符用这样的形式表示{数字}
如果现在是第一个内容{0},第二个内容是{1}
在MessageFormat类中主要有format()方法,此方法的定义如下
public static String format(String pattern,Object...arguments);
事例
定义message_zh_CN.properties文件
info=u4F60u597DuFF0C{0}
定义message_en_US.properties文件
info=hello,{0}
在test类中测试
package com.qn.gj;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
public class interDemo1 {
public static void main(String[] args) {
Locale zhLoc=new Locale("zh","CN");//表示中文地区
Locale enLoc=new Locale("en","US");//表示英文地区
//找到中文的属性文件,需要指定中文Locale
ResourceBundle zhrb=ResourceBundle.getBundle("message",zhLoc);
//找到英文的属性文件,需要指定英文Locale
ResourceBundle enrb=ResourceBundle.getBundle("message",enLoc);
String zhStr=zhrb.getString("info");//根据key值取得value
String enStr=enrb.getString("info");//根据key值取得value
System.out.println("中文:"+MessageFormat.format(zhStr,"中文"));
System.out.println("英文:"+MessageFormat.format(zhStr,"英文"));
}
}
结果
可变参数
在JDK1.5之后java增加了新特性,可以向方法中传递可变的参数,以前定义的方法,实际上里面的参数都是固定个数的,那么在JDK1.5之后为了解决操作的麻烦,增加了这个特性
测试参数传递
package com.qn.gj;
public class Test {
public static void main(String[] args) {
System.out.println("第一次运行");
fun("fdsa","fds","df","b");
System.out.println("第二次运行");
fun("qining");
}
public static void fun(Object ...arg){//固定语法三个点,输入任意多个数据,使用数组的方式进行处理
for (int i = 0; i < arg.length; i++) {
System.out.println(arg[i]+"、");
}
}
}
结果
也可以传递一个数组过去
package com.qn.gj;
public class Test {
public static void main(String[] args) {
String str[]={"fdsa","fds","df","b"};
System.out.println("第一次运行");
fun(str);
System.out.println("第二次运行");
Object str1[]={"qining"};
fun(str1);
Object str2[]={};
fun(str2);
}
public static void fun(Object ...arg){//固定语法三个点,输入任意多个数据,使用数组的方式进行处理
for (int i = 0; i < arg.length; i++) {
System.out.println(arg[i]+"、");
}
}
}
结果
使用一个类代替一个文件
上面的应用就是国际化的实际操作效果
所有的要显示的内容实际上应该存放在资源文件之中,但是在java中为了照顾部分习惯于使用类的用户,所以也可以直接使用一个类来保存资源文件内容,
但是此类在操作的时候就必须继承一个ListResourceBundle类
下面以中文信息为准
事例
定义属性文件
message_zh_CN.properties
info=u4F60u597D,{0}
定义类
package com.qn.gj;
import java.util.ListResourceBundle;
public class message_zh_CN extends ListResourceBundle{
private final Object data[][]={{"info","中文,你好,{0}"}};
protected Object[][] getContents() {
return data;
}
}
在tese类中进行测试
package com.qn.gj;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
public class interDemo1 {
public static void main(String[] args) {
Locale zhLoc=new Locale("zh","CN");//表示中文地区
//找到中文的属性文件,需要指定中文Locale
ResourceBundle zhrb=ResourceBundle.getBundle("message",zhLoc);
String str=zhrb.getString("info");
System.out.println("中文:"+MessageFormat.format(str,"齐宁"));
}
}
结果
不管是资源类还是资源文件,找到的时候都是message,那么如果现在多种资源文件一起出现,那么最先找哪一个?
这时候就要区分优先级了
message_zh_CN.class
message_zh_CN.properties
message.class