http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/java/util/ResourceBundle.html
ResourceBundle類
ResourceBundle類主要作用是讀取屬性文件,讀取屬性文件時可以直接指定屬性文件的名稱(指定名稱時不需要文件的后綴),也可以根據Locale所指定的區域碼來選取指定的資源文件,ResourceBundle類的常用方法如表11-4所示。
表11-4 ResourceBundle類的常用方法
序號
|
方 法
|
類型
|
描 述
|
1
|
public static final ResourceBundle
getBundle (String baseName)
|
普通
|
取得ResourceBundle的實例,
并指定要操作的資源文件名稱
|
2
|
public static final ResourceBundle
getBundle (String baseName,Locale locale)
|
普通
|
取得ResourceBundle的實例,
并指定要操作的資源文件名稱和區域碼
|
3
|
public final String getString(String key)
|
普通
|
根據key從資源文件
中取出對應的value
|
如果現在要使用ResourceBunlde對象,則肯定直接通過ResourceBundle類中的靜態方法getBundle()取得。下面通過一個范例簡單介紹ResourceBundle類的使用。
范例:通過ResourceBundle取得資源文件中的內容
(1)定義資源文件:Message.properties
- info = HELLO
(2)從資源文件中取得內容
- import java.util.ResourceBundle;
-
public class InterDemo01 {
-
public static void main(String[] args) {
-
ResourceBundle rb = ResourceBundle.
getBundle("Message") ;// 找到資
- 源文件
-
System.out.println("內容:" + rb.
getString("info")) ;// 從資源文件中
- 取得內容
- }
- }
程序運行結果:
內容:HELLO
從以上程序中可以發現,程序通過資源文件中的key取得了對應的value。
Java國際化程序實現
11.3.3節中的代碼演示了ResourceBundle類的作用,下面就在程序中結合Locale類一起完成一個國際化的程序開發。
下面完成一個簡單的國際化操作,可以根據Locale所選擇的國家不同,輸出不同國家的"你好!"。
中文:你好!
英語:Hello!
法語:Bonjour!
首先根據不同的國家代碼建立不同的屬性文件,建立的屬性文件與生成的*.class保存在同一個文件夾中。因為現在程序要使用的有3種語言,所以要定義3種屬性文件,在屬性文件定義時必須按照"名稱_國家代碼"的形式命名,即所有相關的屬性文件的名稱全部一樣,只有國家代碼不一樣,代碼如下所示。
(1)中文的屬性文件:Message_zh_CN.properties
- info = "u4f60"u597d"uff01
實際上以上的信息就是中文的"你好!",在屬性文件的操作中是不能直接寫入中文的,就算是寫入了中文,讀取出來的也必然是亂碼,因此必須將相應的中文變為Unicode編碼才可以,要成功地將一個中文編碼變為Unicode編碼,可以直接在運行處執行"native2ascii.exe"命令,輸入相應的中文之后會自動將其進行編碼。
(2)英語的屬性文件:Message_en_US.properties
- info = Hello!
(3)法語的屬性文件:Message_fr_FR.properties
- Info = Bonjour!
- 通過Locale類和ResourceBundle類讀取屬性文件的內容,代碼如下。
-
import java.util.Locale;
-
import java.util.ResourceBundle;
-
public class InterDemo02 {
-
public static void main(String[] args) {
-
Locale zhLoc = new Locale("zh", "CN"); // 表示中國地區
-
Locale enLoc = new Locale("en", "US"); // 表示美國地區
-
Locale frLoc = new Locale("fr", "FR"); // 表示法國地區
-
// 找到中文的屬性文件
-
ResourceBundle zhrb = ResourceBundle.getBundle("Message",zhLoc) ;
-
// 找到英語的屬性文件
-
ResourceBundle enrb = ResourceBundle.getBundle("Message",enLoc) ;
-
// 找到法語的屬性文件
-
ResourceBundle frrb = ResourceBundle.getBundle("Message",frLoc) ;
-
// 依次讀取各個屬性文件的內容,通過鍵值讀取,此時的鍵值名稱為"info"
-
System.out.println("中文:" + zhrb.getString("info")) ;
-
System.out.println("英語:" + enrb.getString("info")) ;
-
System.out.println("法語:" + frrb.getString("info")) ;
- }
- }
程序運行結果:
中文:你好!
英語:Hello!
法語:Bonjour!
從以上程序中可以清楚地發現,根據Locale所指定的國家不同,讀取的資源文件也不同,這樣也就實現了國際化程序。
處理動態文本(1)
在以上程序中,所有資源內容都是固定的,但是輸出的消息中如果包含了一些動態文本,則必須使用占位符清楚地表示出動態文本的位置,占位符使用"{編號}"的格式出現。使用占位符之后,程序可以直接通過MessageFormat對信息進行格式化,為占位符動態設置文本的內容。
MessageFormat是Format類的子類,Format類主要實現格式化操作,除了MessageFormat子類外,Format還有NumberFormat、DateFormat兩個子類,這兩個子類的使用在本章的后面部分均有講解,讀者先來了解MessageFormat類的作用。
U提示:關于Format子類的說明。
在進行國際化操作時,不光只有文字需要處理,實際上數字的顯示、日期的顯示都要符合各個區域的要求,讀者可以通過"區域和語言選項"對話框觀察到這一點,如圖11-5所示。
|
圖11-5 控制面板中的區域和語言選項 |
在這里要同時改變的有數字、貨幣、時間等,所以Format類提供了3個子類,即MessageFormat、DateFormat、NumberFormat。
例如,現在要輸出的信息(以中文為例)是"你好,xxx!",其中,xxx的內容是由程序動態設置的,所以,此時修改之前的3個屬性文件,讓其動態地接收程序的3個文本。
(1)中文的屬性文件:Message_zh_CN.properties
- info = "u4f60"u597d"uff0c{0}"uff01
以上信息就是中文的"你好,{0}!"。
(2)英語的屬性文件:Message_en_US.properties
- info = Hello,{0}!
(3)法語的屬性文件:Message_fr_FR.properties
- info = Bonjour,{0}!
在以上3個屬性文件中,都加入了"{0}",表示一個占位符,如果有更多的占位符,則直接在后面繼續加上"{1}"、"{2}"即可。
然后繼續使用之前的Locale類和ResourceBundle類讀取資源文件的內容,但是讀取之后的文件因為要處理占位符的內容,所以要使用MessageFormat類進行處理,主要使用以下方法:
- public static String format(String pattern,Object…arguments)
以上方法中第1個參數表示要匹配的字符串,第2個參數"Object…arguments"表示輸入參數可以任意多個,沒有個數的限制。
范例:使用MessageFormat格式化動態文本
- import java.text.MessageFormat;
-
import java.util.Locale;
-
import java.util.ResourceBundle;
-
public class InterDemo03 {
-
public static void main(String[] args) {
-
Locale zhLoc = new Locale("zh", "CN"); // 表示中國地區
-
Locale enLoc = new Locale("en", "US"); // 表示美國地區
-
Locale frLoc = new Locale("fr", "FR"); // 表示法國地區
-
// 找到中文的屬性文件
-
ResourceBundle zhrb =ResourceBundle.getBundle("Message",zhLoc) ;
-
// 找到英語的屬性文件
-
ResourceBundle enrb =ResourceBundle.getBundle("Message",enLoc) ;
-
// 找到法語的屬性文件
-
ResourceBundle frrb =ResourceBundle.getBundle("Message",frLoc) ;
-
// 依次讀取各個屬性文件的內容,通過鍵值讀取,此時的鍵值名稱為"info"
-
String str1 = zhrb.getString("info") ;
-
String str2 = enrb.getString("info") ;
-
String str3 = frrb.getString("info") ;
-
System.out.println("中文:" + MessageFormat.format(str1,"李興華")) ;
-
System.out.println("英語:" + MessageFormat.format(str2,"LiXingHua")) ;
-
System.out.println("法語:" + MessageFormat.format(str3,"LiXingHua")) ;
- }
- }
程序運行結果:
中文:你好,李興華!
英語:Hello,LiXingHua!
法語:Bonjour,LiXingHua!
以上程序代碼通過MessageFormat.format()方法設置動態文本的內容,如果有更多的占位符則可按照圖11-6所示設置多個參數。
|
(點擊查看大圖)圖11-6 為多個占位符設置多個動態文本 |
處理動態文本(2)
U提示:Java新特性--可變參數傳遞中可以接收多個對象。
在方法傳遞參數時可以使用如下的形式:
- 返回值類型 方法名稱(Object…args)
表示方法可以接收任意多個參數,然后按照數組的方式輸出即可,代碼如下所示。
范例:測試參數傳遞
- public class InterDemo04 {
-
public static void main(String[] args) {
-
System.out.print("第一次運行:");
-
fun("LXH","Li","李興華") ; // 傳入3個參數
-
System.out.print(""n第二次運行:");
-
fun("MLDN") ; // 傳入1個參數
- }
-
public static void fun(Object...args){ //
可以輸入任意多個數據,使用數組
- 表示
-
for(int i=0;i<args.length;i++){
-
System.out.print(args[i] + "、");
- }
- }
- }
程序運行結果:
第一次運行:LXH、Li、李興華、
第二次運行:MLDN、
從程序的運行結果中可以發現,無論在方法調用時輸入多少個參數,方法都可以接收,接收參數之后可以直接以數組的形式對參數進行輸出。
在其他的資料中讀者也可能看到使用數組的方式向可變參數傳遞內容,代碼如下所示。
范例:使用數組傳遞參數
- package org.lxh.demo11.interdemo;
-
public class InterDemo05 {
-
public static void main(String[] args) {
-
System.out.print("第一次運行:");
-
Object[] arg1 = {"LXH","Li","李興華"} ;
// 對象數組,保存所有具體內容
-
fun(arg1) ; // 傳入3個參數
-
System.out.print(""n第二次運行:");
-
Object[] arg2 = {"MLDN"} ;
-
fun(arg2) ; // 傳入1個參數
-
System.out.print(""n第三次運行:");
- Object[] arg3 = {} ;
-
fun(arg3) ; // 沒有參數傳入
- }
-
public static void fun(Object...args){ // 可變參數
-
for(int i=0;i<args.length;i++){
-
System.out.print(args[i] + "、");
- }
- }
- }
程序運行結果:
第一次運行:LXH、Li、李興華、
第二次運行:MLDN、
第三次運行:
從運行結果來看,兩種方式是一樣的,沒有任何的區別,讀者可以根據個人喜好來選擇,并沒有強制性的規定。