(Java)国际化程序

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

但是实现国际化程序只靠 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"));//从资源文件中取得内容
    }
}

在这里插入图片描述
可以看出程序通过资源文件中的 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!

属性文件中不能直接写入中文,不然会出现乱码,因此需要将相应的中文变为 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"));//从资源文件中取得内容
    }
}

在这里插入图片描述
可以看出根据 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}!

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

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

语句中第一个参数表示要匹配的字符串,第二个参数“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"));
    }
}

在这里插入图片描述
程序代码通过 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;
    }
}
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,"中文"));
    }
}

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

注意
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值