深入ResourceBundle

ResourceBundle是java開發中非常實用的一個類,主要用來處理應用程序多語言這樣的國際化問題。

如果你的應用程序如果有國際化的需求,可以考慮使用ResourceBundle, 你要做的就是給出滿足特定格式的Properties 文件,例如

resource.propreties

resource_zh_CN.properties

resource_ja_JP.properties.

然後應用程序使用ResourceBundle.getBundle(“resource”, locale) 就可以自動的搜索的相應Locale的Properties 文件。

雖然看起來很方便,但使用起來需要注意兩個問題: 1 Properties 文件的搜索次序, 2.  決定是否能找到Properties 文件的ClassLoader , 這也是很多初學者遇到的問題

1.  搜索次序。

先來看個例子,假設你的系統只有兩個Properties

(1) resource.zh_CN.properties : 中文的Properties

(2) resource.properties  : 英文的Properties

假設你Java 的default locale是zh_CN,  如果你調用 ResourceBundle.getBundle(“resource”, Locale.US) , 你覺得系統會使用哪一個文件中的內容?

很多人會覺得會使用resource.properties 中的內容, 但實際上不是這樣的,當你傳入一個Locale.US 給ResourceBundle的時候 ,  ResourceBundle的搜索次序是這樣:
(1) resource_en_US.properties     --- 沒找到
(2) resource_en.properties           --- 還是沒找到
(3) resource_zh_CN.properties  ---- default locale, 找到了
(4) resource_zh_properties      
(5) resource.properties              

注意,ResourceBundle會自動的加上一個default locale 即 zh_CN 來搜索

系統沒有找到xxxx__en_US.properties,  也沒有找到xxx_en.properties, 而是找到了xxx_zh_CN.properties, 就會使用其中的內容, 所以你看的的是中文的結果。

實際上ResourceBundle 搜索結束以後,會建立一個ResourceBundle 對象的Chain, 對於上面的例子會是這樣:

ResourceBundle_2  [locale=zh_CN , parent = ResourceBundle_1]

ResourceBundle_1 [locale = empty parent = null]

你可能要問,這個鏈表中問什麼沒有en_US,en 和zh相關的信息?   這是因爲他們相關的Properties 不存在, 沒有必要加入這個鏈表中。

如果你的應用程序訪問resource文件的一個值得時候, 系統會先在ResourceBundle_2[Locale=zh_CN] 這個對象中找, 如果找到,直接返回相應的值

如果沒有找到,順着parent 即ResourceBundle_1繼續尋找, 如果還沒有找到,只好返回null 了, 因爲沒有parent 了

2. ClassLoader

這個也是經常出問題的地方, 很多時候當你準備好各種Locale 的Properties 文件, 調用ResourceBundle.getBundle(“resource”, Locale.US) 時,系統總是告訴你, 找不到resource_en_US的文件, 很是令人抓狂。

主要的原因就是ClassLoader 不對 ,有空接着寫 :-)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章