关键词搜索

源码搜索 ×
×

(Java)国际化程序

发布2020-01-31浏览536次

详情内容

国际化操作是在开发中较为常见的一种要求,实际上国际化的操作就是指一个程序可以同时适应多门语言,即如果现在程序的使用者是中国人,则会显示中文,如果是英文人,则会显示英语,也就是通过国际化操作让一个程序适应各个国家的语言要求。

但是实现国际化程序只靠 Local类时不够的,还需要属性文件和 ResourceBundle 类的支持,所谓的属性文件是指后缀为 “.properties” 的文件,文件中的内容保存结构为“key=value”形式。

因为国际化的程序只是显示的语言不同,那么就可以根据不同的国家定义不同的属性文件,属性文件中保存真正要使用的文字信息,要访问这些属性文件,可以使用 ResourceBundle 类来完成。

一、国际化程序的实现思路

例如,现在有一个程序要求可以同时适应法语、英语、中文的显示,那么此时就必须使用国际化:
在这里插入图片描述
从图中可以得知,需要根据各个不同的国家配置不同的资源文件(资源文件有时也称为属性文件,后缀为.properties)所有的资源文件以“key->value”的形式出现,在程序执行中只是根据 key 找到 value 并将 value 的内容进行显示,也就是说,只要 key 不变,value 的内容可以任意更换。

如果要实现 Java 程序的国际化操作必须通过以下三个类完成:

java.util.Local:用于表示一个国家语言类
java.util.ResourceBundle:用于访问资源文件
java.util.MessageFormat:格式化资源文件的占位字符串

    这 3 个类的具体操作是通过 Local 类所指定的区域码,然后 ResourceBundle 根据 Local 类所指定的区域码找到相应的资源文件,如果资源文件中存在动态文本,则使用 MessageFormat 进行格式化。

    资源文件有时也称为属性文件,可以直接使用 Java 类集中提供的 Properties 类进行操作

    二、Local 类

    Local 类时实现国际化的一个重要类
    在这里插入图片描述
    实际上对于各个国家都有对应的 ISO 编码,例如,中国的编码为 zh-CN、英语-美国的编码为 en-US。

    三、ResourceBundle 类

    这个类的主要作用是读取属性文件,读取属性文件时可以直接指定属性文件的名称(指定名称时不需要文件的后缀),也可以根据 Local 所指定的区域码来选取指定的资源文件。
    在这里插入图片描述
    如果现在要使用 ResourceBundle 对象,则肯定直接通过 ResourceBundle 类中的静态方法 getBundle() 取得:

    import java.util.ResourceBundle;
    
    public class Test{
        public static void main(String[] args) {
            ResourceBundle rb = ResourceBundle.getBundle("Message");//找到资源文件
            System.out.println("内容:" + rb.getString("info"));//从资源文件中取得内容
        }
    }
    
      4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    可以看出程序通过资源文件中的 key 取得了对应的 value。

    四、Java 国际化程序实现

    完成一个简单的国际化操作,可以根据 Local 所选择的国家不同,输出不同国家的“你好”

    中文:你好!
    英语:Hello!
    法语:Bonjour
    

      首先根据不同的国家代码建立不同的属性文件,建立的属性文件与生产的*.class保存在同一个文件夹中。因为现在程序中使用的有三种语言,所以要定义 3 种属性文件,在属性文件定义时必须按照“名称_国家代码”的形式命名,即所有相关的属性文件的名称全部一样,只有国家代码不一样

      1)中文的属性文件:Message_zh_CN.properties
      	info = \u4f60\u597d\uff01
      (2)英语的属性文件:Message_en_US.properties
      	info = Hello!3)法语的属性文件:Message_fr_FR.properties
      	info = Bonjour!
      
        4
      • 5
      • 6

      属性文件中不能直接写入中文,不然会出现乱码,因此需要将相应的中文变为 Unicode 编码才可以,要成功地将一个中文编码变为 Unicode 编码,可以直接在运行处执行 native2ascii.exe 命令,输入相应的中文之后会自动将其进行编码

      import java.util.Locale;
      import java.util.ResourceBundle;
      public class Test{
          public static void main(String[] args) {
              Locale zhLoc = new Locale("zh","CN");//表示中国地区
              Locale enLoc = new Locale("en","US");//表示美国地区
              Locale frLoc = new Locale("fr","FR");//表示法国地区
              //找到中文的属性文件
              ResourceBundle zhrb = ResourceBundle.getBundle("Message",zhLoc);
              //找到英文的属性文件
              ResourceBundle enrb = ResourceBundle.getBundle("Message",enLoc);
              //找到法语的属性文件
              ResourceBundle frrb = ResourceBundle.getBundle("Message",frLoc);
              System.out.println("中文:" + zhrb.getString("info"));//从资源文件中取得内容
              System.out.println("英语:" + enrb.getString("info"));//从资源文件中取得内容
              System.out.println("法语:" + frrb.getString("info"));//从资源文件中取得内容
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

      在这里插入图片描述
      可以看出根据 Local 所指定的国家不同,读取的资源文件也不同,这样就实现了国际化程序

      五、处理动态文本

      如果输出的消息中包含了一些动态文本,则必须使用占位符清楚地表示出动态文本的位置,占位符使用“{编号}”的格式出现。使用占位符后,程序可以直接通过 MessageFormat 对信息进行格式化,为占位符动态设置文本的内容。

      MessageFormat 是 Format 类的子类,Format 类主要实现格式化操作,除了 MessageFormat 子类外,Format 还有 NumberFormat、DateFormat 两个子类

      在进行国际化操作时,不光只有文字需要处理,实际上数字的显示,日期的显示都要符合各个区域的要求

      此时如果要输出“你好,XXX!”,其中XXX 的内容是由程序动态设置的,所以,此时修改之前的 3 个属性文件,让其动态地接收程序的 2 个文本。

      1)中文的属性文件:Message_zh_CN.properties
      	info = \u4f60\u597d\uff0c{0}\uff01 //意思是中文的“你好,{0}!”2)英语的属性文件:Message_en_US.properties
      	info = Hello,{0}!
      
        4

      此时两个属性文件都加入了{0},表示一个占位符,如果要更多的占位符,则直接在后面继续加上“{1}”,“{2}”即可。
      然后继续使用之前的 Local 类和 ResourceBundle 类读取资源文件的内容,但是读取之后的文件因为要处理占位符的内容,所以要使用 MessageFormat 类进行处理:

      public static String format(String pattern,Object...arguments)
      
      • 1

      语句中第一个参数表示要匹配的字符串,第二个参数“Object…arguments”表示输入参数可以任意多个,没有个数的限制

      import java.text.MessageFormat;
      import java.util.Locale;
      import java.util.ResourceBundle;
      public class Test{
          public static void main(String[] args) {
              Locale zhLoc = new Locale("zh","CN");//表示中国地区
              Locale enLoc = new Locale("en","US");//表示美国地区
              //找到中文的属性文件
              ResourceBundle zhrb = ResourceBundle.getBundle("Message",zhLoc);
              //找到英文的属性文件
              ResourceBundle enrb = ResourceBundle.getBundle("Message",enLoc);
              //依次读取各个属性的内容,通过键值名称为"info"
              String str1 = zhrb.getString("info");
              String str2 = enrb.getString("info");
      
              System.out.println("中文:" + MessageFormat.format(str1,"中文"));
              System.out.println("英文:" + MessageFormat.format(str2,"English"));
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      在这里插入图片描述
      程序代码通过 MessageFormat.format() 方法设置动态文本的内容,如果有更多的占位符可以按照:
      在这里插入图片描述

      六、使用类代替资源文件

      可以使用属性文件保存所有的资源信息,在 Java 中也可以使用类来保存所有的资源信息,但是并不多见

      同理,如果使用类保存信息,也必须按照 key-value 的形式出现,而且类的命名必须与属性文件一致,而且此类必须继承 ListResourceBundle 类,继承之后要覆写此类中的 getContent() 方法:

      建立类文件Message_zh_CN.java

      import java.util.ListResourceBundle;
      public class Message_zh_CN extends ListResourceBundle{
          private final Object data [][] = {
                  {"info","你好,{0}"}
          };
          public Object [][] getContents(){//覆写方法
              return data;
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      import java.text.MessageFormat;
      import java.util.Locale;
      import java.util.ResourceBundle;
      
      public class Test{
          public static void main(String[] args) {
              Locale zhLoc = new Locale("zh","CN");//表示中国地区
              //找到中文的属性文件
              ResourceBundle zhrb = ResourceBundle.getBundle("Message",zhLoc);
              //依次读取各个属性的内容,通过键值名称为"info"
              String str = zhrb.getString("info");
              System.out.println("中文:" + MessageFormat.format(str,"中文"));
          }
      }
      
        4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      在这里插入图片描述
      这里使用类代替了资源文件,但是资源类中的属性一定是一个二维数组

      注意
      在这里插入图片描述

      相关技术文章

      点击QQ咨询
      开通会员
      返回顶部
      ×
      微信扫码支付
      微信扫码支付
      确定支付下载
      请使用微信描二维码支付
      ×

      提示信息

      ×

      选择支付方式

      • 微信支付
      • 支付宝付款
      确定支付下载