一 介紹
國際化(Internationalization)是設(shè)計一個適用于多種語言和地區(qū)的應(yīng)用程序的過程。適用于多種語言和地區(qū)的含義是當(dāng)使用不同語言及處于不同的地區(qū)的用戶在使用這個應(yīng)用程序時,應(yīng)用程序必須使用他們能看懂的語言和符合他們文化習(xí)慣來顯示信息。國際化有時候被簡稱為i18n,因為有18個字母在國際化的英文單詞的字母i和n之間。
一個國際化的程序通常具有以下特征:
- 有一個附加的本地化數(shù)據(jù)(localized data)及擁有在全世界各個地區(qū)執(zhí)行的能力。
- 文本的元素,比如狀態(tài)信息或GUI截面的lables,不是直接寫(hardcoded)在程序中,而是被存儲在本地化的數(shù)據(jù)中,并且能被程序正確的動態(tài)的使用。
- 支持新的語言時,不需要修改程序,不需要重新編譯。
- 文化差異的數(shù)據(jù),比如日期和貨幣,必須根據(jù)擁護的語言和習(xí)慣顯示不同的格式。
- 可以被迅速的本地化。
本地化(Localization)是指通過增加本地描述的構(gòu)件(locale-specific components )和文字翻譯工作來使應(yīng)用程序適應(yīng)于不同的語言和地區(qū)的過程。本地化有時候被簡稱為l10n,應(yīng)為有10個字母在本地化的英文單詞的字母l和n之間。通常本地化最耗時的工作應(yīng)該是文字翻譯。本地化工作者們要根據(jù)地區(qū)的具體需求來為日期、數(shù)字和通貨等數(shù)據(jù)建立新的格式。其他類型的數(shù)據(jù),象聲音,圖象等,也需要根據(jù)具體需要來決定是否本地化。
下面通過一個簡單的例子來說明如何給一個程序提供國際化的特性。這個例子在不同的語言環(huán)境下顯示不同的文本信息。
一個簡單的例子
先看下面的一段代碼:
public class NotI18N {
static public void main(String[] args) {
System.out.println("Hello.");
System.out.println("How are you?");
System.out.println("Goodbye.");
}
}
如果你決定在上面的程序中給德國和法國的不同用戶顯示同樣的信息。但是你的程序員卻不是個語言專家,他不懂德語和法語。所以你需要翻譯人員把它翻譯成德語和法語,但是你的翻譯人員不懂程序,所以你可以把這些信息存到一個文本或其他格式的文件中供翻譯人員使用。那么,程序必須能顯示不同語言的信息,并且你并不知道你希望為這個程序提供的下一個語言支持是什么,或許是日語或許是別的什么語言。
下面的代碼是一個國際化的代碼的例子:
import java.util.*;
public class I18NSample {
static public void main(String[] args) {
String language;
if (args.length != 2) {
language = new String("en");
country = new String("US");
} else {
language = new String(args[0]);
country = new String(args[1]);
}
Locale currentLocale;
ResourceBundle messages;
currentLocale = new Locale(language, country);
messages = ResourceBundle.getBundle("MessagesBundle",
currentLocale);
System.out.println(messages.getString("greetings"));
System.out.println(messages.getString("inquiry"));
System.out.println(messages.getString("farewell"));
}
}
請注意:在上面的代碼中,信息并沒有被hardcoded在代碼中!
如果想運行上面的代碼,請下載下面的文件:
1、I18NSample.java
2、MessageBundle.properties
3、MessageBundle_de_DE.properties
4、MessageBundle_en_US.properties
5、MessageBundle_fr_FR.properties
下面看看這個程序的運行結(jié)果:
顯示法語信息:
java I18NSample fr FR
Bonjour.Comment allez-vous?
Au revoir.
顯示英語信息:
java I18NSample en US
Hello.
How are you?
Goodbye.
從上面的代碼我們可以看出,在實現(xiàn)了國際化的代碼中,并沒有將需要顯示的信息直接hardcode在代碼中,而是存在一個文件中供程序使用。程序根據(jù)不同的語言和國家(Local)來取得文件中不同信息顯示。我們試著按一下的步驟一步一步分析這段代碼如何實現(xiàn)了國際化:
1、建立properties文件----本地化數(shù)據(jù)
properties文件用來存儲程序和環(huán)境相關(guān)的信息。必須以.properties的后綴結(jié)尾,properties文件是純文本格式的。在上面的例子中,一共有4個properties文件。分別定義了不同語言和國家的打招呼、再見和問候時使用的語言。properties文件使用名值對(key-value)的形式,如下所示:
greetings = Bonjour.
farewell = Au revoir.
inquiry = Comment allez-vous?
properties文件的名字很重要,它的形式是basename_LL_CC.properties.LL表示語言代碼,CC表示國家代碼。語言代碼和國家代碼是Local類初始化的參數(shù),basename是創(chuàng)建ResourceBundle對象的參數(shù)。
2、創(chuàng)建Local對象----不同語言和國家的標識
java.util.Local是JDK提供的標準API。這個類用來標識國家和語言。
我們可以創(chuàng)建一個local對象:
aLocale = new Locale("en","US");
這個對象標志了一個地方,這個地方是美國,并且這里的語言是英語。
這下面2個對象又表示什么呢?
caLocale = new Locale("fr","CA");
frLocale = new Locale("fr","FR");
caLocale對象標志的是加拿大并且那里使用了法語,而frLocal標志的是法國而那里的語言是法語。
注意:Local對象只是一個標識類,創(chuàng)建了這個類的對象并不表示你的程序已經(jīng)實現(xiàn)了國際化。這個類是給那些需要實現(xiàn)國際化的類使用的,它用來標識我們即將實現(xiàn)國際化的Local信息。
3、創(chuàng)建ResourceBundle對象----本例中實現(xiàn)國際化的主要角色
java.util.ResourceBundle是JDK提供的標準API。它實際上是個抽象類,同時它提供了創(chuàng)建它的子類的靜態(tài)工廠方法。在例子程序中我們實際上使用的是ResourceBundle的子類PropertyResourceBundle的對象。通過它,我們可以根據(jù)Local對象來讀取不同的properties文件,從而取得不同的信息。
如果local = new Locale("en","US");則讀取了MessagesBundle_en_US.properties文件。
在例子中,用如下語句創(chuàng)建這個對象:
message = ResourceBundle.getBundle("MessagesBundle", currentLocale);
4、用ResourceBundle讀取信息----本地化實現(xiàn)了
讀取了propeties文件后,我們就可以用ResourceBundle的實例通過getString(String Key)方法來取得信息了。如下的語句所示:
String msg1 = messages.getString("greetings");
結(jié)論:
如上面的例子所示,實現(xiàn)國際化實際上并不困難。他需要你做一些計劃,并在程序中加入少量的額外編碼。本章只是簡介,在后面的章節(jié)中我們會了解JAVA的更多國際化的高級特性。