每个面向国际的语言都需要有自己的国际化解决方案。Java从一开始就使用Unicode来处理所有的字符串,这使得Java国际化的一个重要特征。除了提供Unicode之外,Java还需要处理不同语言环境的表示。Localejava.util包提供了Locale类来处理不同语言和地区的国际化问题。使用Locale类自定义一个区域的信息,Locale类提供了以下构造方法来构造Locale对象。publicfinalclassLocaleimplementsCloneable,Serializable{//根据语言、国家和变体构建语言环境publicLocale(Stringlanguage,Stringcountry,Stringvariant){···}//根据语言和国家构建语言环境publicLocale(Stringlanguage,Stringcountry){···}//根据语言代码构造localepublicLocale(Stringlanguage){···}}根据构造方法,构造Locale可以设置语言、国家或地区、变量body.语言用2或3个小写字母表示,如zh、en或de。可以在此处查看ISO-639-1语言代码标识符。Locale中预定义了大量的Locale语言。他们只设置语言而不设置国家,如下所示。//英语publicstaticfinalLocaleENGLISH=createConstant("en","");//法语publicstaticfinalLocaleFRENCH=createConstant("fr","");//德语publicstaticfinalLocaleGERMAN=createConstant("de","");//意大利语publicstaticfinalLocaleITALIAN=createConstant("it","");//日语publicstaticfinalLocaleJAPANESE=createConstant("ja","");//韩语publicstaticfinalLocaleKOREAN=createConstant("ko","");//中文publicstaticfinalLocaleCHINESE=createConstant("zh","");//简体中文publicstaticfinalLocaleSIMPLIFIED_CHINESE=createConstant("zh","CN");//繁体中文publicstaticfinalLocaleTRADITIONAL_CHINESE=createConstant("zh","TW");国家和地区也用2个字母或3个数字表示,如CN、US或DE。可在此处查看ISO-3166-1中的国家或地区名称。Locale中还为每个国家/地区预定义了Locale对象,如下所示。//法国publicstaticfinalLocaleFRANCE=createConstant("fr","FR");//德国publicstaticfinalLocaleGERMANY=createConstant("de","DE");//意大利publicstaticfinalLocaleITALY=createConstant("it","IT");//日本publicstaticfinalLocaleJAPAN=createConstant("ja","JP");//韩国publicstaticfinalLocaleKOREA=createConstant("ko","KR");//中国publicstaticfinalLocaleCHINA=SIMPLIFIED_CHINESE;//中华民国publicstaticfinalLocalePRC=SIMPLIFIED_CHINESE;//台湾publicstaticfinalLocaleTAIWAN=TRADITIONAL_CHINESE;//英国publicstaticfinalLocaleUK=createConstant("en","GB");//美国publicstaticfinalLocaleUS=createConstant("en","US");//加拿大publicstaticfinalLocaleCANADA=createConstant("en","CA");//加拿大法语publicstaticfinalLocaleCANADA_FRENCH=createConstant("fr","CA");//表示根区域设置的常量publicstaticfinalLocaleROOT=createConstant("","");variant,用于指定各种杂项特征,如果有多个变量值,每个变量值表示自己的语义,值应按重要性排序,并用下划线分隔。变体字段区分大小写。Locale除了可以构造Locale对象的构造方法外,JavaSE7还提供了forLanguageTag静态方法构造Locale对象,如下:LocalezhChinese=Locale.forLanguageTag("zh-CN");LocaletwChinese=Locale.forLanguageTag("zh-TW");System.out.println(zhChinese.getDisplayName());System.out.println(twChinese.getDisplayName());//Chinese(中国)//Chinese(台湾)Locale方法setDefault即可更改默认区域,并使用getDefault方法获取当前Locale对象,如下:getDefault());//en-USLocaleen-USLocale中提供的静态方法getAvailableLocale会返回一个由JVM识别的所有Locale组成的数组。ResourceBundle使用Locale设置好具体的语言和地区后,就可以使用ResourceBundle根据不同的Locale来加载资源了。资源需要放在resources资源包中,根据不同的Locales设置相应的资源文件。如下图,通过ResourceBundle类提供的getBundle静态方法,根据locale自动绑定对应的资源文件。Localelocale=Locale.CHINA;ResourceBundlebundle=ResourceBundle.getBundle("i18n",locale);要查找特定的字符串,可以调用Stringlanguage=bundle.getString("language");这里资源文件的名称是统一的命名规则,然后根据不同的区域,来标识其本地信息的附加部分。例如资源包名称为i18n,则对应中英文环境的资源如下图所示。这里可以把默认资源放在一个没有后缀的i18n文件中,然后getBundle方法定位到i18n_zh_CN时,会继续搜索i18n_zh和默认文件i18n这两个文件。如果这些文件存在,它们将成为资源层次父文件中的i18n_zh_CN。以后在查找资源的时候,如果在当前资源文件中没有找到,就会去查找它的父资源文件。在后缀为.properties的文件中,属性以=-分隔的键值对形式存在,如下所示:language=Chinesecolor=redResourceBundle是一个抽象类,如下所示。publicabstractclassResourceBundle{...}继承ResourceBundle的类有一个具体的实现类PropertyResourceBundle和一个抽象类ListResourceBundle。而PropertyResourceBundle是一个具体的子类,用于支持ResourceBundle读取properties资源文件,但不需要直接使用PropertyResourceBundle,ResourceBundle.getBundle会自动找到对应的property文件,并创建引用它的PropertyResourceBundle。但是properties资源文件提供的值只能是字符串。如果要提供其他资源,则需要继承ListResourceBundle抽象类,将所有资源放入一个对象数组中,并提供搜索功能,如下所示。publicclassI18NextendsListResourceBundle{@OverrideprotectedObject[][]getContents(){returnnewObject[][]{{"color","yellow"}};}}publicclassI18N_zhextendsListResourceBundle{@OverrideprotectedObject[][]getContents(){returnnewObject[][]{{"language",newString[]{"简体中文","繁体中文"}}};}}publicclassI18N_zh_CNextendsListResourceBundle{@OverrideprotectedObject[][]getContents(){returnnewObject[][]{{"language","简体中文"},{"color",newString[]{"红色","黄色","黑色"}}};}}这里的类命名规则也是使用标准的命名规则来命名的。然后使用getBundle方法加载对应的类:ResourceBundlebundle=ResourceBundle.getBundle("I18N",Locale.forLanguageTag("zh-CN"));System.out.println(bundle.getString("language"));System.out.println(Arrays.toString(bundle.getStringArray("color")));另外,资源包类也可以继承ResourceBundle类进行扩展,但是需要实现两个方法,一是枚举所有的键,二是使用给定的键找到对应的值:Enumeration
