所谓的国际化的程序指的是能够根据不一样的国家实现不一样的语言描述,可是程序处理的核心业务是相同的html
--若是想要进行国际化的程序开发须要解决以下问题:java
a.如何能够定义保存文字的文件信息
b.如何额能够根据不一样的区域语言的编码读取指定的资源信息编程
一.Locale类工具
--经过分析发现,若是想要实现国际化,那么首先须要解决的就是不一样国家用户的区域和语言编码的问题,而在java.util包中提供有一个专门描述区域和语言编码的类post
--然后主要可使用Locale中的两个构造方法进行实例化this
Locale(String language)
从语言代码构建语言环境。
Locale(String language, String country)
从语言和国家构建语言环境。
Locale(String language, String country, String variant)
从语言,国家和变体构建语言环境。
--国际化对照表参考:每一个国家对应的语言Locale和国家代码对照表--此时须要的是国家和语言的代码,而中文的代码为:zh_CN 美国英语的代码:en_US编码
--范例:实例化Local对象url
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 }
--运行结果spa
zh_CN 3d
--若是说想要自动得到当前的运行环境,那么就能够利用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
--固然若是本地的区域资源文件也不存在时,那么读取的就是没有区域的资源文件,即读取的前后顺序为:
读取指指定区域的资源文件 > 默认的本地资源 > 没有区域设置的资源文件
四.消息格式化
--若是说如今某一个用户登陆成功了,那么通常都会显示这样的信息,"XXX,欢迎您的光临",那么此时若是这些内容保存在了资源文件里面,则就须要经过占位符来进行描述,同时对于读取出来的数据也须要进行消息格式化,正如上文所说的欢迎来到XXX系统,那么这个XXX就是须要格式化的字符串内容,可是XXX这样的预留显得并非特别方便,常规的可使用{0}{1}这样的形式占位,对资源文件做出以下修改
--此时若是要进行文件的资源读取,那么占位符的信息也将一块儿读取出来,因此此时就须要利用MessageFormat类来完成,咱们能够发现MessageFormat类是Format类的子类
1 Class MessageFormat 2 java.lang.Object 3 java.text.Format 4 java.text.MessageFormat
--范例,实现国际化:
1 class MyMessageFormatDemo{ 2 public static void main(String[] args) { 3 ResourceBundle bundle = ResourceBundle.getBundle("test.Messages"); 4 String welcome = bundle.getString("welcome"); 5 String format = MessageFormat.format(welcome, "\n国际化模拟程序\n"); 6 System.out.println(format); 7 } 8 }
--运行结果
1 欢迎来到 2 国际化模拟程序 3 系统 4
5 Process finished with exit code 0
--在实际的开发过程之中,见到资源文件中出现有{0},{1}这样的结构,说明该信息必定是占位符,须要惊进行信息的格式化