国际化的操作就是指一个程序可以同时适应多门语言,即:如果现在程序的使用者是中国人,则会以中文显示,如果现在程序的使用者是英国人,则会以英文 显示,也就是通过国际化操作,让一个程序适应过个国家的语言,程序根据不同的语言环境找到不同的资源文件,资源文件的内容是以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=\u4F60\u597D

在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=\u4F60\u597D\uFF0C{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=\u4F60\u597D,{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