码迷,mamicode.com
首页 > 其他好文 > 详细

国际化的程序实现及其原理

时间:2019-08-18 00:23:33      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:前期准备   local   注意   turn   国际化   object   读取资源文件   文件信息   extends   

国际化的程序实现原理

  所谓的国际化的程序指的是可以根据不同的国家实现不同的语言描述,但是程序处理的核心业务是相同的

--如果想要进行国际化的程序开发需要解决如下问题:

a.如何可以定义保存文字的文件信息
b.如何额可以根据不同的区域语言的编码读取指定的资源信息

一.Locale类

--通过分析发现,如果想要实现国际化,那么首先需要解决的就是不同国家用户的区域和语言编码的问题,而在java.util包中提供有一个专门描述区域和语言编码的类

--而后主要可以使用Locale中的两个构造方法进行实例化

Locale(String language)
从语言代码构建语言环境。
Locale(String language, String country)
从语言和国家构建语言环境。
Locale(String language, String country, String variant)
从语言,国家和变体构建语言环境。 

 

--国际化对照表参考:每个国家对应的语言Locale和国家代码对照表--此时需要的是国家和语言的代码,而中文的代码为:zh_CN  美国英语的代码:en_US

 --范例:实例化Local对象

1 public class MyLocale {
2     public static void main(String[] args) {
3         Locale locale = new Locale("zh","cn");    //表示中文环境
4         System.out.println(locale);
5     }
6 }

--运行结果

 zh_CN 

--如果说想要自动获得当前的运行环境,那么就可以利用Local类本身默认的方式进行实例化:

static Locale    getDefault()
获取Java虚拟机的此实例的默认语言环境的当前值。 
1 public class MyLocale {
2     public static void main(String[] args) {
3         Locale locale = new Locale("en","us");    //表示英文环境
4         System.out.println(locale);
5         System.out.println(Locale.getDefault());
6     }
7 }

--运行结果

en_US
zh_CN

Process finished with exit code 0

--在实际的开发过程之中,很多人可能并不关心国家和语言的编码,所以为了简化开发,Locale类也将世界上比较著名的语言的代码参数设置为了常量:

static Locale    CANADA
对国家有用的常数。
static Locale    CANADA_FRENCH
对国家有用的常数。
static Locale    CHINA
对国家有用的常数。
static Locale    CHINESE
有用的语言常数
static Locale    ENGLISH
有用的语言常数
static Locale    FRANCE
对国家有用的常数。
static Locale    FRENCH
有用的语言常数
static Locale    GERMAN
有用的语言常数
static Locale    GERMANY
对国家有用的常数。
static Locale    ITALIAN
有用的语言常数
static Locale    ITALY
对国家有用的常数。
static Locale    JAPAN
对国家有用的常数。
static Locale    JAPANESE
有用的语言常数
static Locale    KOREA
对国家有用的常数。
static Locale    KOREAN
有用的语言常数
static Locale    PRC
对国家有用的常数。
static char    PRIVATE_USE_EXTENSION
私人使用扩展(‘x‘)的关键。
static Locale    ROOT
根区域的常用常数。
static Locale    SIMPLIFIED_CHINESE
有用的语言常数
static Locale    TAIWAN
对国家有用的常数。
static Locale    TRADITIONAL_CHINESE
有用的语言常数
static Locale    UK
对国家有用的常数。
static char    UNICODE_LOCALE_EXTENSION
Unicode区域扩展(‘u‘)的关键。
static Locale    US
对国家有用的常数。 

--运行结果
1
public class MyLocale { 2 public static void main(String[] args) { 3 Locale locale = new Locale("en","us"); //表示英文环境 4 System.out.println(locale); 5 System.out.println(Locale.getDefault()); 6 System.out.println(Locale.CHINA + " " + Locale.US); 7 } 8 }
en_US
zh_CN
zh_CN en_US

Process finished with exit code 0

二.读取资源文件 ResourceBundle

--当我们准备好资源文件,那么随后就需要进行资源文件耳朵读取操作,可以使用java.util.ResourceBundle类来完成,此类的定于如下

public abstract class ResourceBundle
extends Object

可以发现ResourceBundle类是一个抽象类,如果说现在想要进行此类对象的实例化,可以直接利用该类中提供的静态方法来完成

static ResourceBundle getBundle(String baseName) 
使用指定的基本名称,默认语言环境和调用者的类加载器获取资源包。  
static ResourceBundle getBundle(String baseName, Locale locale) 
使用指定的基本名称和区域设置以及调用者的类加载器获取资源包。  
static ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) 
使用指定的基本名称,区域设置和类加载器获取资源包。  
static ResourceBundle getBundle(String baseName, Locale targetLocale, ClassLoader loader, ResourceBundle.Control control) 
使用指定的基本名称,目标语言环境,类加载器和控件返回资源包。  
static ResourceBundle getBundle(String baseName, Locale targetLocale, ResourceBundle.Control control) 
使用指定的基本名称,目标语言环境和控件以及调用者的类加载器返回资源包。  
static ResourceBundle getBundle(String baseName, ResourceBundle.Control control) 
使用指定的基本名称,默认语言环境和指定的控件返回资源包。  

--baseName是资源文件的名称,但是没有后缀

--范例:使用ResourceBundle类读取内容,如果资源没有放在包里面,则直接编写资源名称即可

技术图片

技术图片

--在这里,需要注意一下资源文件的编写事项,如梭我们直接在资源文件中书写中文字符,那么在使用ResourceBundle类的静态方法获取到资源文件时,得到的结果将会是乱码  

1 class MyResourceBundle{
2     public static void main(String[] args) {
3         ResourceBundle message = ResourceBundle.getBundle("message");
4         System.out.println(message.getString("welcome"));
5     }
6 }

--运行结果 

"»¶Ó­À´µ½XXXϵͳ"

Process finished with exit code 0

 --为了避免这种现象的发生,我们需要将中文字符转化为Unicode码.可以通过JDK安装路径下bin文件中的该工具实现

技术图片

技术图片

--将该转义结果复制到我们的资源文件中

技术图片

--再次执行程序得到结果

1 class MyResourceBundle{
2     public static void main(String[] args) {
3         ResourceBundle message = ResourceBundle.getBundle("message");
4         System.out.println(message.getString("welcome"));
5     }
6 }

--运行结果

欢迎来到XXX系统

Process finished with exit code 0

 --如果说没有读取到我们的资源文件,会出现如下异常

Exception in thread "main" java.util.MissingResourceException: Can‘t find bundle for base name messagse, locale zh_CN
    at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1573)
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1396)
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:782)
    at 常用类库.国际化编程.MyResourceBundle.main(MyLocale.java:20)

Process finished with exit code 1

 --在进行资源读取的时候,获取的资源文件的key值必须存在,否则会发生如下异常

Exception in thread "main" java.util.MissingResourceException: Can‘t find resource for bundle java.util.PropertyResourceBundle, key welcomes
    at java.util.ResourceBundle.getObject(ResourceBundle.java:450)
    at java.util.ResourceBundle.getString(ResourceBundle.java:407)
    at 常用类库.国际化编程.MyResourceBundle.main(MyLocale.java:21)

 三.实现国际化程序

--在完成国际化程序实现的前期准备完成之后,就可以依靠资源文件,Locale类以及ResourceBundle类来完成国际化程序的处理操作

--范例:进行国际化的程序实现(核心关键:读取资源信息)

1.在CLASSPATH下建立国际化源文件:

 技术图片

--将之前所建立的无区域的资源文件也放入test包中,其中共有三个可供选择的资源文件

--通过程序进行指定区域的资源文件的加载

1 class LocaleTest {
2     public static void main(String[] args) {
3         ResourceBundle bundle = ResourceBundle.getBundle("test.Messages");
4         System.out.println(bundle.getString("welcome"));
5     }
6 }

--运行结果

欢迎来到XXX系统

Process finished with exit code 0

--我们发现在使用ResourceBundle进行资源文件读取时并没有指定一个明确的Locale对象,但是发现中文的资源文件起作用了,因为这个方法里面默认加载的就是当前本地的资源文件

1     @CallerSensitive
2     public static final ResourceBundle getBundle(String baseName)
3     {
4         return getBundleImpl(baseName, Locale.getDefault(),
5                              getLoader(Reflection.getCallerClass()),
6                              getDefaultControl(baseName));
7     }

 --可以发现在方法内部调用了Locale.getDefault()方法获取当前的区域编码,如果现在有需要也可以修改当前的Locale环境,则可以使用ResourceBundle类中的如下方法

1 class LocaleUSTest{
2     public static void main(String[] args) {
3         ResourceBundle bundle = ResourceBundle.getBundle("test.Messages",Locale.US);
4         System.out.println(bundle.getString("welcome"));
5     }
6 }

 --运行结果

welcome to this system

Process finished with exit code 0

 --如果现在有指定区域的资源文件存在的时候,那么没有设置区域的资源文件的信息将不会被读取,例如读取不存在资源文件的区域代码时,则将会读取我们本地的资源文件

1 class LocaleUSTest{
2     public static void main(String[] args) {
3         ResourceBundle bundle = ResourceBundle.getBundle("test.Messages",Locale.UK);
4         System.out.println(bundle.getString("welcome"));
5     }
6 }

 --运行结果

欢迎来到XXX系统

Process finished with exit code 0

 --当然如果本地的区域资源文件也不存在时,那么读取的就是没有区域的资源文件,即读取的先后顺序为:

  读取指指定区域的资源文件 > 默认的本地资源 > 没有区域设置的资源文件  例

国际化的程序实现及其原理

标签:前期准备   local   注意   turn   国际化   object   读取资源文件   文件信息   extends   

原文地址:https://www.cnblogs.com/skykuqi/p/11370431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!