Java 国际化

Java国际化编程

目录

java支持的国家与语言

我们可以通过下面程序的运行结果知道Java支持的国家与语言。

public class LocaleList {
    public static void main(String[] args) {
        // 返回Java所支持的全部国家的语言
        Locale[] localesList = Locale.getAvailableLocales();
        // 便利数组的每个元素,依次获取所支持国家的语言
        for (int i = 0; i < localesList.length; i++) {
            // 输出所支持国家的语言
            System.out.println(localesList[i].getDisplayCountry()
                + "=" + localesList[i].getCountry() + " "
                + localesList[i].getDisplayLanguage()
                + "=" + localesList[i].getLanguage());
        }
    }
}

最简单的hello World程序

对于一个最简单的Hello World程序

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

对于这个最简单的Hello World程序,现在需要这个程序在不同国家的电脑上都能实现一个简单的打招呼。当然要与本国语言相同。
这里需要提供几个文件:
base.propertise
文件内容如下:

hello=你好!

base_zh_CN.properties
文件的内容如下:

hello=你好!

base_en_US.properties
文件的内容如下:

hello=Welcome you!

对于包含非ASCII码的文件需要使用Java提供的工具native2ascii来转化。
这个工具可以在%JAVA_HOME%/bin下找到,当然用的使用只需要在命令提示窗口像编译Java程序一样使用。
具体的用法如下:
native2ascii 原资源文件 目标资源文件
例如:
native2ascii base.properties base_zh_US.properties
当然如果使用IDE时可以使用一些插件(有些插件是自带的)。
这里以idea为例:在Setting->Preferences–>Editor–>FileCodings中将Preferences–>Editor–>FileCodings勾上
只是因为编码不同,idea一般设置的编码是utf-8,而资源文件是ascii。
具体用法也很简单
参见idea官网英文的可以翻译看看。
下面是这个程序的代码:

public class ReHello
{
    public static void main(String[] args)
    {
        // 取得系统默认的国家/语言环境
        Locale myLocale = Locale.getDefault(Locale.Category.FORMAT);
        // 根据指定国家/语言环境加载资源文件
        ResourceBundle bundle = ResourceBundle
                .getBundle("Java基础库类.base" , myLocale);
        // 打印从资源文件中取得的消息
        System.out.println(bundle.getString("hello"));
    }
}

需要注意的是:如果此程序在某个包下,必须在hello前加包名。
测试
英文时可以将系统语言调成美国的。
但是也可以通过下面的程序完成。

public class ReHello
{
    public static void main(String[] args)
    {
        // 取得系统默认的国家/语言环境
        Locale myLocale = new Locale("en", "US");
        // 根据指定国家/语言环境加载资源文件
        ResourceBundle bundle = ResourceBundle
                .getBundle("Java基础库类.base" , myLocale);
        // 打印从资源文件中取得的消息
        System.out.println(bundle.getString("hello"));
    }
}

下面是API中对这些方法的解释

Enum Locale.Category
枚举地区类别。 这些区域设置类别用于获取/设置由类别表示的特定功能的默认语言环境。
public static Locale getDefault(Locale.Category category)获取Java虚拟机的此实例的指定类别的默认语言环境的当前值。
Java虚拟机根据主机环境在启动期间设置默认语言环境。 如果没有显式指定区域设置,则会被许多区域设置敏感的方法使用。 它可以使用setDefault(Locale.Category,Locale)方法更改。
public static final Locale.Category FORMAT用于表示格式化日期,数字和/或货币的默认区域设置的类别。
getBundle
public static final ResourceBundle getBundle(String baseName, Locale locale)使用指定的基本名称、语言环境和调用者的类加载器获取资源包。
getString
public final String getString(String key)从此资源包或它的某个父包中获取给定键的字符串。

更多内容请自行阅读API文档。

使用MessageFormat处理包占位符的字符串

如果需要输入的东西是可变的
比如说要输出一个
你好 xxx!今天是 xxxx-xx-xx x午 xx:xx。
需要准备的文件是:
mess.properties文件的内容是:
你好 {0}!今天是 {1}。
mess_en_US.properties文件的内容是:
Hello {0}! Today is {1}.

public class HelloAre {
    public static void main(String[] args) {
        Locale currentlocale = null;
        if(args.length == 2) {
            currentlocale = new Locale(args[0], args[1]);
        }
        else {
            currentlocale = Locale.getDefault(Locale.Category.FORMAT);
        }
        ResourceBundle bundle = ResourceBundle.getBundle("Java基础库类.mess", currentlocale);
        String msg = bundle.getString("msg");
        System.out.println(MessageFormat.format(msg, "Peter", new Date())
        );
    }
}

public final StringBuffer format(Object arguments,
StringBuffer result,
FieldPosition pos)格式化一个对象数组,并将 MessageFormat 的模式添加到所提供的 StringBuffer,用格式化后的对象替换格式元素。这等效于

使用类来代替资源文件

条件是:
1. 类名必须是baseName_language_country,与文件的命名相似。
2. 该类必须继承 ListResourceBundle,并且重写getContents()方法,该方法返回Object数组,该数组的每一项都是key-value。
例如:

import java.util.*;
public class myMess_zh_CN extends ListResourceBundle {
    private final Object[][] myDate = {
            {"msg", "{0},你好,今天的日期是{1}"}
    };
    public Object[][] getContents() {
        return myDate;
    }
}

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

使用NumberFormat格式化数字

MessageFromat 是抽象类Fromat的子类,Fromat抽象类还有两个子类:NumberFromat和DateFromat,他们分别实现数值、日期装换成字符串。
NumberFromat也是有个抽象类,无法透过构造器来创建NumberFromat对象,但可以通过类方法来创建。
1. getCurrencyInstance() : 返回默认的Locale的货币格式器。也可以调用该方法时传入指定的Locale,则获取指定的Local货币格式器。
2. getPercentInstance() : 返回默认locale的百分数格式器。也可以指定。
3. getIntegerInstance() : 返回默认整数格式器。也可以指定。
4. getNumberInstance() : 返回默认的通用数值格式器。也可以指定。

import java.text.NumberFormat;
import java.util.*;
public class NumberFormatDemo {
    public static void main(String[] args) {
        double a = 12334.00;
        Locale[] locales = {Locale.CHINA, Locale.JAPAN, Locale.US, Locale.UK};
        NumberFormat[] numberFormats = new NumberFormat[12];
        for (int i = 0; i < locales.length; i++) {
            numberFormats[i*3] = NumberFormat.getNumberInstance(locales[i]);
            numberFormats[i*3 + 1] = NumberFormat.getPercentInstance(locales[i]);
            numberFormats[i*3 + 2] = NumberFormat.getCurrencyInstance(locales[i]);
        }
        for (int i = 0; i < locales.length; i++) {
            String str = i == 0 ? "中国的格式:" : i == 1 ? "日本的格式:" :
                i == 2 ? "美国的格式:" : "英国得格式";
            System.out.println(str);
            System.out.println("通用格式:" + numberFormats[i*3].format(a));
            System.out.println("百分格式:" + numberFormats[i*3 + 1].format(a));
            System.out.println("货币数值格式格式:" + numberFormats[i*3 + 2].format(a));
        }
    }
}

使用DateFromat

DateFormat与NumbeFormat相似。

getDateFormat() : 返回一个日期格式器,格式化后的字符串只有日期。
getTimeFormat() : 返回一个时间格式器,格式化后的字符串只有时间,没有日期。
getDateTime() : 返回一个日期时间格式器,格式化后的字符串有日期、时间。
以上的方法都可以传入多个参数,用于指定日期的样式、时间的样式和Locale等参数。如果不指定就使用默认参数。

import static java.text.DateFormat.*;
import java.text.DateFormat;
import java.util.*;
public class DateFormatDemo {
    public static void main(String[] args) {
        Date date = new Date();
        Locale[] locales = {Locale.CHINA, Locale.US};
        DateFormat[] dateFormats = new DateFormat[16];
        for (int i = 0; i < locales.length; i++) {
            dateFormats[i*8] = DateFormat.getTimeInstance(SHORT, locales[i]);
            dateFormats[i*8 + 1] = DateFormat.getTimeInstance(MEDIUM, locales[i]);
            dateFormats[i*8 + 2] = DateFormat.getTimeInstance(LONG, locales[i]);
            dateFormats[i*8 + 3] = DateFormat.getTimeInstance(FULL, locales[i]);
            dateFormats[i*8 + 4] = DateFormat.getDateInstance(SHORT, locales[i]);
            dateFormats[i*8 + 5] = DateFormat.getDateInstance(MEDIUM, locales[i]);
            dateFormats[i*8 + 6] = DateFormat.getDateInstance(LONG, locales[i]);
            dateFormats[i*8 + 7] = DateFormat.getDateInstance(FULL, locales[i]);
        }
        for (int i = 0; i < locales.length; i++) {
            String str = i == 0 ? "中国的格式" : "美国格式";
            System.out.println(str);
            System.out.println("SHORT时间格式器:" + dateFormats[i*8].format(date));
            System.out.println("MEDIUM时间格式器:" + dateFormats[i*8 + 1].format(date));
            System.out.println("LONG时间格式器:" + dateFormats[i*8 + 2].format(date));
            System.out.println("FULL时间格式器:" + dateFormats[i*8 + 3].format(date));
            System.out.println("SHORT日期格式器:" + dateFormats[i*8 + 4].format(date));
            System.out.println("MEDIUM日期格式器:" + dateFormats[i*8 + 5].format(date));
            System.out.println("LONG日期格式器:" + dateFormats[i*8 + 6].format(date));
            System.out.println("FULL日期格式器:" + dateFormats[i*8 + 7].format(date));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值