java.util.ResourceBundle用法詳解

初識(shí)國際化和ResourceBundle
這個(gè)類主要用來解決國際化和本地化問題。國際化和本地化可不是兩個(gè)概念,兩者都是一起出現(xiàn)的。可以說,國際化的目的就是為了實(shí)現(xiàn)本地化,詳細(xì)的介紹可以看本文的最后。比如對(duì)于“取消”,中文中我們使用“取消”來表示,而英文中我們使用“cancel”。若我們的程序是面向國際的(這也是軟件發(fā)展的一個(gè)趨勢),那么使用的人群必然是多語言環(huán)境的,實(shí)現(xiàn)國際化就非常有必要。而ResourceBundle可以幫助我們輕松完成這個(gè)任務(wù):當(dāng)程序需要一個(gè)特定于語言環(huán)境的資源時(shí)(如 String),程序可以從適合當(dāng)前用戶語言環(huán)境的資源包(大多數(shù)情況下也就是.properties文件)中加載它。這樣可以編寫很大程度上獨(dú)立于用戶語言環(huán)境的程序代碼,它將資源包中大部分(即便不是全部)特定于語言環(huán)境的信息隔離開來。
這使編寫的程序可以:
輕松地本地化或翻譯成不同的語言
一次處理多個(gè)語言環(huán)境
以后可以輕松進(jìn)行修改,以便支持更多的語言環(huán)境?
測試及驗(yàn)證
下面我們來模擬一個(gè)多語言的環(huán)境
定義四個(gè)資源文件:res_en_US.properties、res_zh_CN.properties、res_zh.properties、res.properties
res_en_US.properties:cancelKey=cancel
res_zh_CN.properties:cancelKey=\u53D6\u6D88(取消)
res_zh.properties:cancelKey=\u53D6\u6D88zh(取消zh)
res.properties:cancelKey=\u53D6\u6D88default(取消default)命名規(guī)則按照:資源名+_語言_國別.properties,每個(gè)資源文件中定義了本地化的信息,那么系統(tǒng)如何取到對(duì)應(yīng)的資源文件呢?
ResourceBundle bundle = ResourceBundle.getBundle("res", new?Locale("zh", "CN"));其中new Locale("zh", "CN");這個(gè)對(duì)象就告訴了程序你的本地化信息,就拿這個(gè)來說吧:程序首先會(huì)去classpath下尋找res_zh_CN.properties,若不存在,那么會(huì)去找res_zh.properties,若還是不存在,則會(huì)去尋找res.properties,要還是找不到的話,那么就該拋異常了:MissingResourceException。
我們可以來寫個(gè)測試程序驗(yàn)證一下:
package bundle.test;
?
import java.util.Locale;
import java.util.ResourceBundle;
?
public?class?BundleTest?{
?
??public?static?void?main(String args[]) {
????ResourceBundle bundle = ResourceBundle.getBundle("res", new?Locale("zh", "CN"));
????String cancel = bundle.getString("cancelKey");
????System.out.println(cancel);
????
????bundle = ResourceBundle.getBundle("res", Locale.US);
????cancel = bundle.getString("cancelKey");
????System.out.println(cancel);
????
????bundle = ResourceBundle.getBundle("res", Locale.getDefault());
????cancel = bundle.getString("cancelKey");
????System.out.println(cancel);
?
????bundle = ResourceBundle.getBundle("res", Locale.GERMAN);
????cancel = bundle.getString("cancelKey");
????System.out.println(cancel);
??}
}輸出:
取消
cancel
取消
取消這里前三個(gè)都在我們的預(yù)期范圍之內(nèi),但是最后一個(gè)GERMAN,應(yīng)該會(huì)去使用res.properties這個(gè)資源包吧?怎么使用了res_zh_CH.properties?
原來ResourceBundle為我們提供了一個(gè)fallback(也就是一個(gè)備用方案),這個(gè)備用方案就是根據(jù)當(dāng)前系統(tǒng)的語言環(huán)境來得到的本地化信息。
所以若是找不到GERMAN的,之后就會(huì)去找CHINA了,所以找到了res_zh_CH.properties這個(gè)資源包。
這點(diǎn)我也是看了源代碼才明白的,下面就貼上一些關(guān)鍵的源代碼:
ResourceBundle baseBundle = null;
??for?(Locale targetLocale = locale;
???????targetLocale != null;
???????targetLocale = control.getFallbackLocale(baseName, targetLocale)) {// 這里就是去拿備用方案的
??????// do something 我們暫時(shí)不關(guān)心
??}跟蹤control.getFallbackLocale(baseName, targetLocale)看看備用方案到底是什么?
public?Locale getFallbackLocale(String baseName, Locale locale) {
??????if?(baseName == null) {
????throw?new?NullPointerException();
??????}
??????Locale defaultLocale = Locale.getDefault();
??????return?locale.equals(defaultLocale) ? null?: defaultLocale;
??}當(dāng)顯式定義的本地化信息并不是當(dāng)前系統(tǒng)的本地化信息時(shí),若未能通過顯式定義的找到資源包,那么就去轉(zhuǎn)而通過當(dāng)前系統(tǒng)的本地化信息去找了~
最后放一點(diǎn)小知識(shí)吧~
國際化和本地化
國際化(Internationalization)是設(shè)計(jì)一個(gè)適用于多種語言和地區(qū)的應(yīng)用程序的過程。適用于多種語言和地區(qū)的含義是當(dāng)使用不同語言及處于不同的地區(qū)的用戶在使用這個(gè)應(yīng)用程序時(shí),應(yīng)用程序必須使用他們能看懂的語言和符合他們文化習(xí)慣來顯示信息。國際化有時(shí)候被簡稱為i18n,因?yàn)橛?8個(gè)字母在國際化的英文單詞的字母i和n之間。
一個(gè)國際化的程序通常具有以下特征:
有一個(gè)附加的本地化數(shù)據(jù)(localized ?data)及擁有在全世界各個(gè)地區(qū)執(zhí)行的能力。
文本的元素,比如狀態(tài)信息或GUI截面的lables,不是直接寫(hardcoded)在程序中,而是被存儲(chǔ)在本地化的數(shù)據(jù)中,并且能被程序正確的動(dòng)態(tài)的使用。
支持新的語言時(shí),不需要修改程序,不需要重新編譯。
文化差異的數(shù)據(jù),比如日期和貨幣,必須根據(jù)擁護(hù)的語言和習(xí)慣顯示不同的格式。
可以被迅速的本地化。
本地化(Localization)是指通過增加本地描述的構(gòu)件(locale-specific components )和文字翻譯工作來使應(yīng)用程序適應(yīng)于不同的語言和地區(qū)的過程。本地化有時(shí)候被簡稱為l10n,應(yīng)為有10個(gè)字母在本地化的英文單詞的字母l和n之間。通常本地化最耗時(shí)的工作應(yīng)該是文字翻譯。本地化工作者們要根據(jù)地區(qū)的具體需求來為日期、數(shù)字和通貨等數(shù)據(jù)建立新的格式。其他類型的數(shù)據(jù),象聲音,圖象等,也需要根據(jù)具體需要來決定是否本地化。
鏈接:csdn.net/u012345283/article/details/42082253
覺得不錯(cuò)就點(diǎn)個(gè)贊哦!
