國際化的程序實現及其原理

國際化的程序實現原理

  所謂的國際化的程序指的是能夠根據不一樣的國家實現不一樣的語言描述,可是程序處理的核心業務是相同的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}這樣的結構,說明該信息必定是佔位符,須要驚進行信息的格式化

相關文章
相關標籤/搜索