ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-08-17 23:01:21  阅读:327  来源: 互联网

标签:国际化 java String 程序实现 Locale ResourceBundle static 原理 资源


国际化的程序实现原理

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

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

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

一.Locale类

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

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

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

--此时需要的是国家和语言的代码,而中文的代码为:zh_CN  美国英语的代码:en_US

--国际化对照表参考:每个国家对应的语言Locale和国家代码对照表

 

--范例:实例化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

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

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

标签:国际化,java,String,程序实现,Locale,ResourceBundle,static,原理,资源
来源: https://www.cnblogs.com/skykuqi/p/11370431.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有