Posted on 2006-07-06 17:48
負(fù)人博客 閱讀(259)
評論(0) 編輯 收藏 所屬分類:
JAVA技術(shù)
語言和地理環(huán)境對我們的文化產(chǎn)生重要影響.我們同他人之間的交流以及生活中的事件都發(fā)生在語言和地理環(huán)境所產(chǎn)生的一個系統(tǒng)里.由于語言和環(huán)境的不同,以至需要我們來制定一個適合的方式來達(dá)到向他人表述我們自己或者我們的想法的目的.為了有效地與他人交流,需要考慮對方的文化,環(huán)境以及使用對方的語言.
類似地,一套有實效的軟件系統(tǒng)也要考慮用戶的語言和地理區(qū)域.語言和區(qū)域形成了本地環(huán)境,描述了軟件本地化的配置和上下文.在Java平臺上,通過java.util.Locale對象來描述本地化.
本文為在Java平臺上的編程人員講解Locale對象以其含義.
本文分成如下幾部分:
. 定義
. 構(gòu)造
. 預(yù)先準(zhǔn)備的各Locale
. 識別可支持的Locale
. 以字符串來表述Locale
. 使用 Locale
. 獲取Locale的信息
. 總結(jié)
定義
Locale確定了一種專門的語言和區(qū)域.通過使用java.util.Locale對象來為那些區(qū)域敏感型的對象定制格式化數(shù)據(jù)以及向用戶的展示.Locale影響到用戶界面的語言,情形映射,整理(排序),日期和時間的格式以及貨幣格式.Locale在很多文化背景和語言敏感型的數(shù)據(jù)操作上的要求很嚴(yán)格.
java.util.Locale是個輕量級對象,包含為數(shù)不多的幾個重要成員:
. 一個語言代號
. 一個國家或者區(qū)域的可選項
. 一個另一形式代號的可選項
談到或者書寫Locale時,為了方便使用,可用縮寫.在這樣的縮寫表述里,使用下劃線來把Locale對象的每部分隔開來:
<language code>[_<country code>[_<variant code>]]
這三部分內(nèi)容提供了足夠的信息讓其他些個區(qū)域敏感型對象為了特定的語言文化來修飾它們的行為.舉例講,java.text.NumberFormat對象格式化出來的數(shù)字同在德語拼寫的奧地利和瑞士是有區(qū)別的.
表一,不同Locale的格式化輸出
Locale formatted Numbers
======================================
German (Germany) 123.456,789
German (Switzerland) 123'456.789
English (United States) 123,456.789
Locale對象是個標(biāo)識符,像jva.text.NumberFormat,java.text.DateFormat這樣的區(qū)域敏感型的對象都會提供本地化的數(shù)字或者日期的格式.舉例說,java.text.DateFormat類在其實例化過程中用Locale對象來正確地定出日期的格式.
以下部分講述locale的各成分
ISO 639制定了語言代號,國際標(biāo)準(zhǔn)組織為世界上的大多數(shù)語言指派2個或者3個字母來代表.Locale用2個字母代號標(biāo)識出想要的語言.表二列出這樣的幾個語言代號.
表二, ISO 639標(biāo)準(zhǔn)里的語言代號的例子
Language Code
=====================
Arabic ar
German de
English en
Spanish es
Japanese ja
Hebrew he
語言環(huán)境是Locale對象里的重要組成部分,因為它描述了特定用戶群的語言.你的應(yīng)用程序需要用這此信息來為用戶提供與其語言一致的用戶界面.
當(dāng)然,語言并沒描繪了整個Locale.舉一例,即使把 de 作為本地語言代號, 單單的一個 de 并不能讓你知道到底是哪一地區(qū)的的人講的德語.一些國家把德語作為官方語言或者作為第二種語言.一個國家與另一個國家里的德語的區(qū)別之一就是排列順序.由于這樣的原因以及另外些原由,語言并不總能充分地準(zhǔn)確地定義一個區(qū)域.
國家(區(qū)域)代號
另一個國際標(biāo)準(zhǔn)ISO 3166定義了國家代號.這個標(biāo)準(zhǔn)為世界上的大多數(shù)主要區(qū)域以及每個國家定義了2到3個的縮寫字母.跟語言代號對比,國家代號是用大寫字符的.表三給出了一些代號定義.Locale用兩字母的代號來替代標(biāo)準(zhǔn)里也同樣支持的3字母的代號
表三,ISO 3166標(biāo)準(zhǔn)中的一些國家代號的定義
Country Code
====================
China CH
Canada CA
France FR
Japan JP
Germany DE
國家代號是Locale的重要組成部分.對應(yīng)日期的java.text.Format對象,時間,數(shù)字和貨幣都對國家代號很敏感.有了國家代號就可更好地確認(rèn)Locale里的語言部分.舉例來說,在加拿大和法國都說法語的,然而確切的用法和語言表達(dá)習(xí)慣卻是不一樣的.這些不同之處可以用Locale里的國家代號來區(qū)分出來.例如, 代號fr_CA(加拿大法語)跟fr_FR(法國法語)就不一樣.
方言
操作系統(tǒng),瀏覽器以及其他軟件供應(yīng)商可用這個代號來提供附加的功能或者到達(dá)語言和國家代號所不能實現(xiàn)的定制.比如說,一家軟件公司也許會為一特定操作系統(tǒng)指定一個locale,于是開發(fā)人員為西班牙的Macintosh操作系統(tǒng)創(chuàng)建了es_ES_MAC或者為Windows操作系統(tǒng)創(chuàng)建es_ES_WIN的本地化.
Java平臺歷史上的一個例子就是使用EURO變量來為歐洲用戶實現(xiàn)本地化.Java 2平臺1.3標(biāo)準(zhǔn)版過度時期里就為歐洲的這些國家的本地化使用了這個變量.比如,盡管已經(jīng)存在了 de_DE(德國德語)的本地化,但還是將 de_DE_EURO(歐洲的德國德語)加進(jìn)了Java環(huán)境里.由于歐元是那些接受歐元流通國家里的標(biāo)準(zhǔn)貨幣,因此這個變量就從 J2SE1.4版本里剔除了.多數(shù)應(yīng)用程序可能不需要這個代號.
構(gòu)造
Locale類有如下幾個構(gòu)造器:
. Locale(String language)
. Locale(String language, String country)
. Locale(String language, String country, String variant)
以下展示每個構(gòu)造器如何使用:
//創(chuàng)建一個通用英語的locale.
Locale locale1 = new Locale("en");
//創(chuàng)建一個加拿大英語的locale.
Locale locale2 = new Locale("en", "CA");
//創(chuàng)建一個美式英語的locale
//硅谷的英語
Locale locale3 = new Locale("en", "US", "SiliconValley");
用ISO 639的兩字母代號表示的en代表了英語.ISO 3166的代號CA和US分別代表加拿大和美國.有個特別:如上代碼片段里最后一行上用一個可選變量en_US_SiliconValley創(chuàng)建locale.
這個locale比第一個locale更明細(xì).不僅說明了是美式英語,還特地講指出是硅谷那邊的.其目的之一是讓開發(fā)者可以定制用戶的本地化,這個變量可以是任何你想要的值.
雖然編譯與運行環(huán)境不關(guān)心你是否指定了你自己的語言或者是別的國家地區(qū),但是你應(yīng)當(dāng)用ISO標(biāo)準(zhǔn)里定義的代號來區(qū)別.強(qiáng)制自己去用ISO標(biāo)準(zhǔn)里的定義,這樣可確保同其他應(yīng)用程序或者代碼標(biāo)準(zhǔn)兼容.
更為重要的一點是,區(qū)域敏感型的類庫僅用ISO代號.比如,java.text.NumberFormat類對于de_DE的本地化是能明白的,但是卻不知如何處置虛構(gòu)的foo_biz.假如用非ISO標(biāo)準(zhǔn)的定義,你不得不寫程序代碼去實現(xiàn)支持那些非ISO標(biāo)準(zhǔn)定義的代號.
預(yù)定義的Locale
Locale類里有幾個Locale類型的靜態(tài)成員實例.比如說,Locale.FRANCE 就是預(yù)先就準(zhǔn)備好的代表法國法語.你可在想要的地方用Locale.FRANCE也可以用new Locale("fr", "FR")的方式來實現(xiàn).表四給出了一些預(yù)定義的現(xiàn)成Locale對象實例
Locale Name Locale
=======================================
Locale.CHINA zh_CN
Locale.CHINESE zh
Locale.SIMPLIFIED_CHINESE zh_CN
Locale.TRADITIONAL_CHINESE zh_TW
Locale.PRC zh_CN
Locale.TAIWAN zh_TW
Locale.ENGLISH en
Locale.UK en_GB
Locale.US en_US
Locale.FRANCE fr_FR
Locale.FRENCH fr
這些個預(yù)定義的Locale對象的實例的存在確實很方便.然而,僅列出的這幾個靜態(tài)成員是有限的,不完整的,并不需要對每個重要的locale都要來描述.支持區(qū)域敏感型的類的locale并不需要在Locale類里有Locale類型的成員常量.比如說,Locale類里就沒有代表南美洲的常量.雖然沒有,但是照樣支持包括日期格式和數(shù)字格式這樣的區(qū)域敏感型的類.
由于僅存在極少量的預(yù)先準(zhǔn)備好的locale,以至你可能回避這些靜態(tài)實例.但是確實存在或者你會在別人的代碼里碰到,所以在此對它們有所提級,盡管它們很方便,但是不靠它們,你的代碼也是可行的.
識別支持的Locales
Java平臺支持什么樣的locale?你可創(chuàng)建你想要的任何locale,然而你的運行時刻環(huán)境不一定全支持你創(chuàng)建的這些locale.
那么你想知道你可以創(chuàng)建什么樣的locale呢?答案很簡單:你可創(chuàng)建任何你要的locale.構(gòu)造器不會在乎非ISO標(biāo)準(zhǔn)的參數(shù).但是從這個提問里引出來:對什么樣的locale,類庫能提供更多信息呢?對什么樣的locale,庫能提供整理,時間,日期,數(shù)字和貨幣的信息呢?也許你會依靠腳本或干脆你來寫能支持運行環(huán)境的系統(tǒng).
以下部分講述如何識別出運行庫能支持的locales.另外還講解了可支持文本組件的書寫.最后,例舉了運行庫中和開發(fā)包里的幾個可用的本地化.
把locale用在java.util包和java.text包
運行時刻環(huán)境并不需要對每個區(qū)域敏感型的類都要用locale來支持.每個區(qū)域敏感型的類實現(xiàn)為它自身支持的一套locale,這套設(shè)置能使類跟類可區(qū)別開來.比如,一個格式化數(shù)字類支持的locale就跟一個日期類支持的locale有所區(qū)別.
另外,不需要所有的運行環(huán)境的實現(xiàn)都要支持同一套locale.但是所有的運行環(huán)境的實現(xiàn)都必須支持一個locale的最小集合.這個集合很小,僅是英語環(huán)境(U.S).幸好,SUN公司提供的運行環(huán)境的實現(xiàn)里提供了更多的支持.盡管這不是形式上所必須的,但是SUN公司提供的各運行環(huán)境的實現(xiàn)里為區(qū)域敏感型的數(shù)據(jù)格式提供了同樣的一套集合.這樣的做法為類提供了一致性.Java 2標(biāo)準(zhǔn)版5.0里對locale支持的指南提供了詳細(xì)的列表說明.表五給出一部分所支持的locales
表五,java.util和java.text包里所支持的部分locales
Language Country Locale ID
==========================================================
Arabic Saudia Arabia ar_SA
Chinese(simplified) China zh_CN
Chinese (traditional) Taiwan zh_TW
Dutch Netherlands nl_NL
English Australia en_AU
English Canada en_CA
English United Kingdom en_GB
English United States en_US
French Canada fr_CA
French France fr_FR
German Germany de_DE
Hebrew Israel he_IL
Hindi India hi_IN
Italian Italy it_IT
Japanese Japan ja_JP
Korean South Korea ko_KR
Portuguese Brazil pt_BR
Spanish Spain es_ES
Swedish Sweden sv_SE
Thai (Western digits) Thailand th_TH
Thai (Thai digits) Thailand th_TH_TH
你得問一問區(qū)域敏感型的類在運行時刻環(huán)境里(JRE)到底支持什么locales.每個區(qū)域敏感型類支持通過實現(xiàn)方法getAvailableLocales()來支持多種locale.比如:
Locale[] localeList = NumberFormat.getAvailableLocales();
java.util和java.text包里有許多類實現(xiàn)了getAvailableLocales()方法.例如,NumberFormat,
DateFormat,Calendar和BreakIterator.
Locale類本身也是本本地化成幾個locale,在下面例子中,一個德國locale實例以英語(默認(rèn)情況下是作者的主機(jī)),德語和法語提供了信息:
Locale deLocale = new Locale("de", "DE");
Locale frLocale = new Locale("fr", "FR");
System.out.println("Default language name (default): " +
deLocale.getDisplayLanguage());
System.out.println("German language name (German): " +
deLocale.getDisplayLanguage(deLocale));
System.out.println("German language name (French): " +
deLocale.getDisplayLanguage(frLocale));
輸出結(jié)果如下
German language name (default): German
German language name (German): Deutsch
German language name (French): allemand
對字符的支持
文本組件通常不支持單個locale.實際上文本組件常在本地上用一套書寫樣式來顯示.
盡管不能從各文本組件上獲取一個所支持的書寫樣式列表,但是這樣的一個列表卻是J2SE 5.0的本地化指南中公開的.
通常,AWT對等體組件在操作系統(tǒng)的支持下可進(jìn)行書寫樣式的展示.如果你的系統(tǒng)是阿拉伯的環(huán)境,那么AWT的文本組件會顯示阿拉伯文字.在一個阿拉伯環(huán)境的系統(tǒng)上,你也能在文本框或者文本域里輸入阿拉伯文.然而你可別指望不在同一語言環(huán)境時這些AWT組件可顯示同樣的文本.比如在一個英語環(huán)境的系統(tǒng)不大可能在文本框里顯示阿拉伯文字.
Java Foundation Classes/Swing (JFC/Swing)組件通常能支持多語言,是因為不依賴主機(jī)系統(tǒng)以及使用UNICODE作為多語言字符集的編碼.因此SWING組件通常可顯示多語言字符而AWT的對等體組件就不能.表六顯示了一些能支持的字符
表六.一些可顯示的文本字符
Writing System Language
=======================================================
Arabic Arabic
Chinese (simplified) Chinese
Chinese (traditional) Chinese
Devanagari Hindi
Hebrew Hebrew
Japanese Japanese
Korean Korean
Latin: Western European English, French, German, Italian,
subset Spanish, Swedish, and so on
Thai Thai
Greek Greek
Cyrillic Belorussian, Russian, and so on
Latin: Baltic subset Latvian, Lithuanian
Latin: Central European subset Czech, Hungarian, Polish, and so on
Latin: Turkic subset Turkish and so on
JRE與SDK的本地化
運行環(huán)境里的幾個用戶界面元素已經(jīng)根據(jù)本地樣式進(jìn)行了本地化.這些元素包括了AWT與SWING的組件以及JRE和SDK產(chǎn)生的消息.表七給出了J2SE 5.0提供的所有本地化
表七.為JRE作的用戶界面的翻譯
Language Locale ID
=================================
Chinese (simplified) zh_CN
Chinese (traditional) zh_TW
English en
French fr
German de
Italian it
Japanese ja
Korean ko
Spanish es
Swedish sv
某些開發(fā)工具,比如JAVA編譯器,僅隨J2SE的軟件開發(fā)包供給.這些工具為用戶提供了出錯,出錯,警告和其他消息.這些工具以及SDK里的實用工具包括編譯器里的消息,被翻譯為英語或者日語.這些翻譯的結(jié)果在J2SE 5.0里已經(jīng)實現(xiàn)了.
以字符串形式描述locale
盡管你使用locale的多數(shù)時候需要引用一個Locale對象,但是有些時候用另一種表現(xiàn)形式會很方便,尤其是進(jìn)行內(nèi)部調(diào)試時候.Locale對象的toString()方法返回String,它是語言,區(qū)域和變種代號的一個串.toString()方法以下劃線來把各部分隔開.這樣,提供了一種方便的可讀性好的形式方便你的調(diào)試.
考慮如下那樣創(chuàng)建locale的代碼
Locale l = new Locale("ja", "JP");
toString()方法將返回 "ja_JP".
如此的字符串不適合提供給最終用戶.大多數(shù)用戶不熟悉ISO 639和ISO 3166標(biāo)準(zhǔn)中的國家和語言的代號,會覺得這樣的字符串不好懂.幸好還有友好用戶界面的文本展示,我們將在本文后面中討論.
使用locale
盡管不常見,Locale對象卻是在JAVA類庫中普遍用到.即使你不明確地要求用locale,JAVA運行環(huán)境也會為你提供缺省的設(shè)置來實現(xiàn)消息和行為的本地化.當(dāng)你明確地使用locale,你可為你的應(yīng)用程序的每個部分使用不同的locale.
譬如,你可用es_MX,西班牙語(墨西哥)的locale來顯示本地化的消息;用en_US,(美式英語)的locale來顯示貨幣和數(shù)字.這方式很適合在美國工作生活的習(xí)慣西班牙語的人.盡管用戶見到的是西班牙語的菜單,提示與文本,但是應(yīng)用程序其他地方可見到按照美國習(xí)慣的貨幣和數(shù)字.這個簡單例子向你展現(xiàn)了如何在一個應(yīng)用程序里使用多種locale.如果你的應(yīng)用程序真是需要這樣的locale支持的話,那么你可自主決定應(yīng)用程序各方面的行為.
除了像格式化數(shù)字,貨幣,日期和時間這樣的區(qū)域敏感型的類之外還提供了如同詞語分解的整理功能.
這些類通常以構(gòu)造器或者是工廠方法來實例化.無論哪種形式,你可按照你喜歡的一種來創(chuàng)建一個詳細(xì)的locale.
使用缺省Locale
無論應(yīng)用程序是否明確指定了詳細(xì)的locale,區(qū)域敏感型的對象都會選用缺省的locale.依賴這缺省的locale很不明智.在多用戶應(yīng)用程序里,不是每個用戶都適合這個缺省的locale,因此應(yīng)用程序應(yīng)當(dāng)為所有的區(qū)域敏感型對象明確指定一個適合的locale.缺省的locale是一種為應(yīng)用程序里所有的區(qū)域敏感型對象提供的系統(tǒng)資源.缺省時,也許對用戶來說可能是對的,但是應(yīng)當(dāng)在多語言和多文化的環(huán)境下明確指定,當(dāng)程序運行在一臺機(jī)器上為多用戶所使用時,這點尤其重要.
用如下的方法來獲得缺省locale:
public static Locale getDefault()
有三種途徑為應(yīng)用程序確定出一個缺省的locale.
第一,除非明確的更改默認(rèn)的locale,否則getDefault()方法返回值的locale是由JAVA虛擬機(jī)首次裝載時確定的.這就是說,JAVA虛擬機(jī)從系統(tǒng)環(huán)境確定出了缺省的locale.系統(tǒng)環(huán)境上的locale是由操作系統(tǒng)和用戶喜好來確定的;
第二,某些JAVA運行環(huán)境的實現(xiàn)里,用戶可通過命令行上設(shè)置user.language, user.country以及 user.variant信息來覆蓋掉系統(tǒng)的缺省locale.
如的代碼會依據(jù)這些設(shè)置的屬性來打印出locale
import java.util.Locale;
public class Default {
public static void main(String[] args) {
System.out.println(Locale.getDefault());
}
}
根據(jù)如上代碼來做個實驗.運行在U.S的英語系統(tǒng)時候,如上代碼會輸出en_US. 假如在命令行上給出選項參數(shù),那么你可讓程序使用任何你想要的locale.例如,為程序提供如下的命令行參數(shù):
java -Duser.language=fr -Duser.country=CA Default
以這樣的方式來運行程序的話,將把fr_CA當(dāng)作默認(rèn)的locale
第三,可通過調(diào)用setDefault(Locale aLocale)方法來實現(xiàn). setDefault(Locale aLocale)方法讓應(yīng)用程序設(shè)置了一個系統(tǒng)級別的資源.在用此方法設(shè)置了缺省的locale后,接著調(diào)用Locale.getDefault()就得到了最新設(shè)置的locale.
注意:別在applet中調(diào)用setDefault()方法.applet的安全管理不會讓你調(diào)用這方法的,因為這個方法調(diào)用的結(jié)果會影響主機(jī)上運行著的JAVA虛擬機(jī)上的系統(tǒng)級別的資源.
大多數(shù)情況下,對于其他類使用缺省locale意味著完全忽略locale.譬如,你想要以缺省locale格式化一個數(shù)字,你可以簡單地而不需要任何參數(shù)來創(chuàng)建NumberFormat:
NumberFormat nf = NumberFormat.getInstance();
如上代碼的情況下使用locale基本上不需要你做什么.另外一些區(qū)域敏感型的類也是照這樣的模式.需要缺省locale的行為的時候不需要作特定的工作來創(chuàng)建.但是缺省行為不是適合所有情況的,因此在特殊時候你還需要明確指定locale.
顯示使用locale
在有些計算機(jī)的環(huán)境中,僅有單一的locale貫穿于整個應(yīng)用程序的生命周期里.另外一些環(huán)境里,應(yīng)用程序使用一個可變的全局locale.在這些環(huán)境里,你可通過編程來改變locale,除非去改動locale,否則它一直保持原先的效果.JAVA應(yīng)用程序環(huán)境很獨特,在應(yīng)用程序里,可依照你想要的任何方式來使用不同的locale.
跨國公司在世界上有許多客戶.這就意味著這些公司的客戶和員工也許使用著不同的語言并且希望公司和公司的軟件能適合他們.此外,很可能也很常見的事是:公司里有個法國雇員為一位意大利客戶處理銷售記錄.在這種情形下,你必須要控制好業(yè)務(wù)以及用戶界面中的對象所使用的locale以便處理和展現(xiàn)數(shù)據(jù).應(yīng)用程序可能在打印銷售收據(jù)時候使用意大利格式的日期和貨幣格式,然而又要為習(xí)慣英語的雇員列客戶清單.還有很多類似這么復(fù)雜的情況沒有列在此處.但是JAVA技術(shù)提供了靈活的方式來處理如此復(fù)雜的情況.
為了最大限度的靈活性,你必須為區(qū)域敏感型的類指定明確的locale.這就意味著你必須為程序的各個方面考慮locale的表現(xiàn)樣式或者為不同的用戶和客戶指定locale.
如果你已經(jīng)為用戶方的locale作了考慮,那么在構(gòu)造器參數(shù)列表里明確指定一個locale或者在一些特定方法里指定以此來創(chuàng)建區(qū)域敏感型的類的實例.設(shè)想有個用來作展現(xiàn)的對象里存儲了為客戶選用的locale:
Locale userLocale = preferences.getLocale();
NumberFormat nf = NumberFormat.getInstance(userLocale);
獲取locale的信息
由于locale對象不包含很多信息,但是提供了一些有趣的方法.正如你想的,這些信息跟語言,國家和方言是有密切聯(lián)系的.其中一些是依賴locale的,另一些則不依賴locale.這些情況說明了locale對象為它的方法提供了兩種不同形式.locale里的一些信息并非是面向客戶或者本地化的,另一些則是本地化的并且適合用來為用戶展現(xiàn)的.
不依賴locale的信息
getLanguage() 方法返回ISO 639 標(biāo)準(zhǔn)中為語言定義的兩字母縮寫.比如,你創(chuàng)建了ja_JP的locale,那么方法返回的是 ja . 這個方法的完整形式是:
public String getLanguage()
ISO 639標(biāo)準(zhǔn)的一個擴(kuò)展是用三個字母縮寫的代號來定義語言的.盡管在J2SE 5.0里不使用這些代號,但是卻是有用的.用如下的方法來獲得三字母縮寫的語言代號:
public String getISO3Language()
看個對比的例子:
Locale aLocale = Locale.JAPAN;
System.out.println("Locale: " + aLocale);
System.out.println("ISO 2 letter: "+ aLocale.getLanguage());
System.out.println("ISO 3 letter: " + aLocale.getISO3Language());
aLocale = Locale.US;
System.out.println("Locale:" + aLocale);
System.out.println("ISO 2 letter: " + aLocale.getLanguage());
System.out.println("ISO 3 letter: " + aLocale.getISO3Language());
輸出結(jié)果如下:
Locale: ja_JP
ISO 2 letter: ja
ISO 3 letter: jpn
Locale: en_US
ISO 2 letter: en
ISO 3 letter: eng
getCountry()方法返回 ISO 3169標(biāo)準(zhǔn)中兩字母縮寫定義的國家或者區(qū)域代號.方法的完整形式: public String getCountry()
也有個ISO擴(kuò)展標(biāo)準(zhǔn)里用三字母縮寫來定義國家代號:public String getISO3Country()
看個對比的例子:
Locale aLocale = Locale.CANADA_FRENCH;
System.out.println("Locale: " + aLocale);
System.out.println("ISO 2 letter: " + aLocale.getCountry());
System.out.println("ISO 3 letter: " + aLocale.getISO3Country());
輸出結(jié)果如下:
Locale: fr_CA
ISO 2 letter: CA
ISO 3 letter: CAN
如果locale對象里設(shè)置有方言的字段的話, getVariant()方法返回一個字符串來表示.如果locale對象里沒設(shè)置方言的字段的話,此方法返回空串.此方法的形式如下:public String getVariant()
locale類中的如下幾個方法可獲取所有可用的語言代號和國家代號:
public static String[] getISOCountries()
public static String[] getISOLanguages()
相對于客戶來說,開發(fā)者更愿意使用getLanguage()方法返回的代號.而客戶可能想要如下文中描述的那些不同之處.
依賴locale的信息
方法getLanguage(), getCountry(), getVariant()返回的代號對于用戶來說不友好.用戶并不需要懂這些代號,因此locale提供另外的一些方法來提供了更具有可讀性的面向客戶的信息.
locale對象提供了一些可返回人能讀懂的文本描述的方法.這些文本描述不同于toString()方法返回的字符串.并非把語言,國家和方言這些字段簡單的串連起來,而是提供了locale的人可讀懂的,本土化了的信息:
public final String getDisplayLanguage()
public final String getDisplayCountry()
public final String getDisplayVariant()
顯示語言
當(dāng)你需要以用戶習(xí)慣的語言來顯示的時候,應(yīng)使用locale對象的getDisplayLanguage()放.此方法返回了可顯示的,人能讀懂的用戶方語言的名稱.假如你不給出目標(biāo)locale的話,這個顯示的名稱就是缺省的locale的本土化.此方法的兩種形式:
public final String getDisplayLanguage()
public final String getDisplayLanguage(Locale targetLocale)
以下舉例如何使用這兩個方法:
Locale deLocale = Locale.GERMANY;
// 系統(tǒng)默認(rèn)的locale是 en_US
String defaultLanguage = deLocale.getDisplayLanguage();
//目標(biāo)locale顯示地指出了使用的語言
String targetLanguage = deLocale.getDisplayLanguage(deLocale);
System.out.println(defaultLanguage);
System.out.println(targetLanguage);
輸出結(jié)果如下:
German
Deutsch
輸出的 German 是以美式英語單詞來顯示locale里所使用的語言.這并沒給你留下特別的印象,但是要注意的是:你怎樣提供一個目標(biāo)locale作參數(shù).這種情形中,getDisplayLanguage()試圖找到和返回一個本土化了的lcoale中語言組件的版本.
這一點很重要,因為你能為客戶顯示應(yīng)用程序可支持的客戶方語言的每個locale的語言名稱.你可在程序里提供一個列表來讓用戶選他們喜好的locale.
這就引來一個有趣的問題:如何在locale的語言環(huán)境里呈現(xiàn)locale的語言名稱?你可按照如下代碼來做:
String displayLang = aLocale.getDisplayLanguage(aLocale);
換言之,就是在調(diào)用getDisplayLanguage()方法時候以此locale對象作參數(shù).對于其他可顯示的locale元素也可使用這個竅門.比如,也能用這種方法來顯示國家和方言.如下代碼演示了這個竅門.
Locale[] locales = { new Locale("en", "US"), new Locale("ja","JP"),
new Locale("es", "ES"), new Locale("it", "IT") };
for (int x=0; x< locales.length; ++x) {
String displayLanguage = locales[x].getDisplayLanguage(locales[x]);
println(locales[x].toString() + ": " + displayLanguage);
}
顯示國家
給用戶顯示locale對象里的國家或者地區(qū)信息時可按照如下代碼:
public final String getDisplayCountry()
public final String getDisplayCountry(Locale targetLocale)
第一種形式的方法為缺省locale提供了本土化的國家名稱.第二種形式的方法為目標(biāo)locale提供了同樣的本土化信息.
Locale deLocale = Locale.GERMANY;
// default en_US
String defaultCountry = deLocale.getDisplayCountry();
// target de_DE
String targetCountry = deLocale.getDisplayCountry(deLocale);
System.out.println(defaultCountry);
System.out.println(targetCountry);
輸出結(jié)果如下:
Germany
Deutschland
顯示方言
方言在locale里相對于其他元素用地比較少.然而有時還需要要獲取它的信息.
getDisplayVariant()方法返回locale里的方言部分的顯示名稱.
public final String getDisplayVariant()
public final String getDisplayVariant(Locale targetLocale)
在JAVA平臺使用方言的一個方法是為支持泰國語言.根據(jù)約定,對于 th 和 th_TH的locale而使用的NumberFormat對象通常以阿拉伯?dāng)?shù)字或者是泰國格式的阿拉伯?dāng)?shù)字來使用.對于th_TH_TH的locale的NumberFormat是用泰國數(shù)字的,如下面的代碼演示:
Locale[] thaiLocale = {new Locale("th"), new Locale("th","TH"),
new Locale("th","TH", "TH")};
for(Locale locale: thaiLocale) {
NumberFormat nf = NumberFormat.getNumberInstance(locale);
StringBuffer msgBuff = new StringBuffer();
msgBuff.append(locale.toString() + ": ");
msgBuff.append(nf.format(573.34));
textArea.append(msgBuff.toString() + "\n");
}
顯示名稱
顯示名稱僅是簡單地組合了本土化語言,國家和剛才演示的方言.方法的形式如下:
public final String getDisplayName()
public final String getDisplayName(Locale targetLocale)
跟locale的toString()方法有所不同.toString()方法是串聯(lián)起來各個部分并且以下劃線分割.
getDisplayName()方法以括號分割各個部分.
Locale deLocale = Locale.GERMANY;
// default en_US
String defaultCountry = deLocale.getDisplayName();
// target de_DE
String targetCountry = deLocale.getDisplayName(deLocale);
System.out.println(defaultCountry);
System.out.println(targetCountry);
輸出結(jié)果如下:
German (Germany)
Deutsch (Deutschland)
總結(jié)
locale是一門語言,一個可選國家(或者一個地區(qū))或者是一個可選方言代號的標(biāo)識符.locale對象提供了幾個方法來獲取關(guān)于locale狀態(tài)的信息.盡管locale本身不包含許多功能,但是區(qū)域敏感型對象依賴于locale來指示行為.區(qū)域敏感型對象用locale來定制它們的行為以此滿足用戶所想要的.
JAVA平臺上,每個區(qū)域敏感型對象負(fù)責(zé)它自身區(qū)域相關(guān)的行為.設(shè)計上,區(qū)域敏感型對象之間互不相干.這就是說,在一個類里被支持的locale并不一定要跟另一個類里被支持的lcoale一樣.
在傳統(tǒng)的操作系統(tǒng)上和區(qū)域模型里,在同一時間里僅有一個locale的設(shè)置起作用.這些系統(tǒng)上,在你通過編程來設(shè)置locale后,所有的區(qū)域敏感型的功能都會使用指定的locale,這個locale猶如一個全局locale一樣貫穿于應(yīng)用程序.當(dāng)以setLocale方法或者類似的調(diào)用使另一個全局locale起作用后才發(fā)生改變.JAVA平臺上,由于處理locale時有些不同,所以一個JAVA應(yīng)用程序里在同一時間可有多個locale起作用.配合格式對象使用多種loalce讓開發(fā)者有機(jī)會為多語言和多文化環(huán)境的應(yīng)用程序創(chuàng)建復(fù)雜的必要的組合.