java.util.ResourceBundle用法詳解

jopen 9年前發布 | 57K 次閱讀 Java開發 ResourceBundle

初識國際化和ResourceBundle

這個類主要用來解決國際化和本地化問題。國際化和本地化可不是兩個概念,兩者都是一起出現的。可以說,國際化的目的就是為了實現本地化,詳細的介紹可以看本文的最后。比如對于“取消”,中文中我們使用“取消”來表示,而英文中我們使用“cancel”。若我們的程序是面向國際的(這也是軟件發展的一個趨勢),那么使用的人群必然是多語言環境的,實現國際化就非常有必要。而ResourceBundle可以幫助我們輕松完成這個任務:當程序需要一個特定于語言環境的資源時(如 String),程序可以從適合當前用戶語言環境的資源包(大多數情況下也就是.properties文件)中加載它。這樣可以編寫很大程度上獨立于用戶語言環境的程序代碼,它將資源包中大部分(即便不是全部)特定于語言環境的信息隔離開來。

這使編寫的程序可以:

  • 輕松地本地化或翻譯成不同的語言
  • 一次處理多個語言環境
  • 以后可以輕松進行修改,以便支持更多的語言環境 

測試及驗證

下面我們來模擬一個多語言的環境
定義四個資源文件: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)

命名規則按照:資源名+_語言_國別.properties,每個資源文件中定義了本地化的信息,那么系統如何取到對應的資源文件呢?
ResourceBundle bundle = ResourceBundle.getBundle("res", new Locale("zh", "CN"));

其中new Locale("zh", "CN");這個對象就告訴了程序你的本地化信息,就拿這個來說吧:程序首先會去classpath下尋找res_zh_CN.properties
若不存在,那么會去找res_zh.properties,若還是不存在,則會去尋找res.properties,要還是找不到的話,那么就該拋異常了:MissingResourceException
我們可以來寫個測試程序驗證一下:

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
取消
取消

這里前三個都在我們的預期范圍之內,但是最后一個GERMAN,應該會去使用res.properties這個資源包吧?怎么使用了res_zh_CH.properties?
原來ResourceBundle為我們提供了一個fallback(也就是一個備用方案),這個備用方案就是根據當前系統的語言環境來得到的本地化信息。
所以若是找不到GERMAN的,之后就會去找CHINA了,所以找到了res_zh_CH.properties這個資源包
這點我也是看了源代碼才明白的,下面就貼上一些關鍵的源代碼:
  ResourceBundle baseBundle = null;
    for (Locale targetLocale = locale;
         targetLocale != null;
         targetLocale = control.getFallbackLocale(baseName, targetLocale)) {// 這里就是去拿備用方案的
        // do something 我們暫時不關心
    }

跟蹤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;
    }

當顯式定義的本地化信息并不是當前系統的本地化信息時,若未能通過顯式定義的找到資源包,那么就去轉而通過當前系統的本地化信息去找了~
最后放一點小知識吧~

國際化和本地化

國際化(Internationalization)是設計一個適用于多種語言和地區的應用程序的過程。適用于多種語言和地區的含義是當使用不同語言及處于不同的地區的用戶在使用這個應用程序時,應用程序必須使用他們能看懂的語言和符合他們文化習慣來顯示信息。國際化有時候被簡稱為i18n,因為有18個字母在國際化的英文單詞的字母i和n之間。

一個國際化的程序通常具有以下特征:
  • 有一個附加的本地化數據(localized  data)及擁有在全世界各個地區執行的能力。
  • 文本的元素,比如狀態信息或GUI截面的lables,不是直接寫(hardcoded)在程序中,而是被存儲在本地化的數據中,并且能被程序正確的動態的使用。
  • 支持新的語言時,不需要修改程序,不需要重新編譯。
  • 文化差異的數據,比如日期和貨幣,必須根據擁護的語言和習慣顯示不同的格式。
  • 可以被迅速的本地化。
        本地化(Localization)是指通過增加本地描述的構件(locale-specific components )和文字翻譯工作來使應用程序適應于不同的語言和地區的過程。本地化有時候被簡稱為l10n,應為有10個字母在本地化的英文單詞的字母l和n之間。通常本地化最耗時的工作應該是文字翻譯。本地化工作者們要根據地區的具體需求來為日期、數字和通貨等數據建立新的格式。其他類型的數據,象聲音,圖象等,也需要根據具體需要來決定是否本地化。

來自:http://blog.csdn.net/u012345283/article/details/42082253
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!