語(yǔ)言和地理環(huán)境對(duì)我們的文化產(chǎn)生重要影響.我們同他人之間的交流以及生活中的事件都發(fā)生在語(yǔ)言和地理環(huán)境所產(chǎn)生的一個(gè)系統(tǒng)里.由于語(yǔ)言和環(huán)境的不同,以至需要我們來(lái)制定一個(gè)適合的方式來(lái)達(dá)到向他人表述我們自己或者我們的想法的目的.為了有效地與他人交流,需要考慮對(duì)方的文化,環(huán)境以及使用對(duì)方的語(yǔ)言.
            
            類似地,一套有實(shí)效的軟件系統(tǒng)也要考慮用戶的語(yǔ)言和地理區(qū)域.語(yǔ)言和區(qū)域形成了本地環(huán)境,描述了軟件本地化的配置和上下文.在Java平臺(tái)上,通過(guò)java.util.Locale對(duì)象來(lái)描述本地化.
            
            本文為在Java平臺(tái)上的編程人員講解Locale對(duì)象以其含義.
            
            本文分成如下幾部分:
            
            . 定義
            . 構(gòu)造
            . 預(yù)先準(zhǔn)備的各Locale
            . 識(shí)別可支持的Locale
            . 以字符串來(lái)表述Locale
            . 使用 Locale
            . 獲取Locale的信息
            . 總結(jié)
            
            定義
            
            Locale確定了一種專門(mén)的語(yǔ)言和區(qū)域.通過(guò)使用java.util.Locale對(duì)象來(lái)為那些區(qū)域敏感型的對(duì)象定制格式化數(shù)據(jù)以及向用戶的展示.Locale影響到用戶界面的語(yǔ)言,情形映射,整理(排序),日期和時(shí)間的格式以及貨幣格式.Locale在很多文化背景和語(yǔ)言敏感型的數(shù)據(jù)操作上的要求很?chē)?yán)格.
            
            java.util.Locale是個(gè)輕量級(jí)對(duì)象,包含為數(shù)不多的幾個(gè)重要成員:
            
            . 一個(gè)語(yǔ)言代號(hào)
            . 一個(gè)國(guó)家或者區(qū)域的可選項(xiàng)
            . 一個(gè)另一形式代號(hào)的可選項(xiàng)
            
            談到或者書(shū)寫(xiě)Locale時(shí),為了方便使用,可用縮寫(xiě).在這樣的縮寫(xiě)表述里,使用下劃線來(lái)把Locale對(duì)象的每部分隔開(kāi)來(lái):
            <language code>[_<country code>[_<variant code>]]
            
            這三部分內(nèi)容提供了足夠的信息讓其他些個(gè)區(qū)域敏感型對(duì)象為了特定的語(yǔ)言文化來(lái)修飾它們的行為.舉例講,java.text.NumberFormat對(duì)象格式化出來(lái)的數(shù)字同在德語(yǔ)拼寫(xiě)的奧地利和瑞士是有區(qū)別的.
            
            表一,不同Locale的格式化輸出
            
            Locale          formatted Numbers
            ======================================
            German (Germany)      123.456,789
            German (Switzerland)    123'456.789
            English (United States)  123,456.789
            
            Locale對(duì)象是個(gè)標(biāo)識(shí)符,像jva.text.NumberFormat,java.text.DateFormat這樣的區(qū)域敏感型的對(duì)象都會(huì)提供本地化的數(shù)字或者日期的格式.舉例說(shuō),java.text.DateFormat類在其實(shí)例化過(guò)程中用Locale對(duì)象來(lái)正確地定出日期的格式.
            
            以下部分講述locale的各成分
            
            ISO 639制定了語(yǔ)言代號(hào),國(guó)際標(biāo)準(zhǔn)組織為世界上的大多數(shù)語(yǔ)言指派2個(gè)或者3個(gè)字母來(lái)代表.Locale用2個(gè)字母代號(hào)標(biāo)識(shí)出想要的語(yǔ)言.表二列出這樣的幾個(gè)語(yǔ)言代號(hào).
            
            表二, ISO 639標(biāo)準(zhǔn)里的語(yǔ)言代號(hào)的例子
            
            Language   Code
            =====================
            Arabic    ar
            German    de
            English    en
            Spanish    es
            Japanese   ja
            Hebrew    he
            
            語(yǔ)言環(huán)境是Locale對(duì)象里的重要組成部分,因?yàn)樗枋隽颂囟ㄓ脩羧旱恼Z(yǔ)言.你的應(yīng)用程序需要用這此信息來(lái)為用戶提供與其語(yǔ)言一致的用戶界面.
            
            當(dāng)然,語(yǔ)言并沒(méi)描繪了整個(gè)Locale.舉一例,即使把 de 作為本地語(yǔ)言代號(hào), 單單的一個(gè) de 并不能讓你知道到底是哪一地區(qū)的的人講的德語(yǔ).一些國(guó)家把德語(yǔ)作為官方語(yǔ)言或者作為第二種語(yǔ)言.一個(gè)國(guó)家與另一個(gè)國(guó)家里的德語(yǔ)的區(qū)別之一就是排列順序.由于這樣的原因以及另外些原由,語(yǔ)言并不總能充分地準(zhǔn)確地定義一個(gè)區(qū)域.
            
            國(guó)家(區(qū)域)代號(hào)
            
            另一個(gè)國(guó)際標(biāo)準(zhǔn)ISO 3166定義了國(guó)家代號(hào).這個(gè)標(biāo)準(zhǔn)為世界上的大多數(shù)主要區(qū)域以及每個(gè)國(guó)家定義了2到3個(gè)的縮寫(xiě)字母.跟語(yǔ)言代號(hào)對(duì)比,國(guó)家代號(hào)是用大寫(xiě)字符的.表三給出了一些代號(hào)定義.Locale用兩字母的代號(hào)來(lái)替代標(biāo)準(zhǔn)里也同樣支持的3字母的代號(hào)
            
            表三,ISO 3166標(biāo)準(zhǔn)中的一些國(guó)家代號(hào)的定義
            
            Country   Code
            ====================
            China      CH
            Canada       CA
            France       FR
            Japan       JP
            Germany   DE
            
            國(guó)家代號(hào)是Locale的重要組成部分.對(duì)應(yīng)日期的java.text.Format對(duì)象,時(shí)間,數(shù)字和貨幣都對(duì)國(guó)家代號(hào)很敏感.有了國(guó)家代號(hào)就可更好地確認(rèn)Locale里的語(yǔ)言部分.舉例來(lái)說(shuō),在加拿大和法國(guó)都說(shuō)法語(yǔ)的,然而確切的用法和語(yǔ)言表達(dá)習(xí)慣卻是不一樣的.這些不同之處可以用Locale里的國(guó)家代號(hào)來(lái)區(qū)分出來(lái).例如, 代號(hào)fr_CA(加拿大法語(yǔ))跟fr_FR(法國(guó)法語(yǔ))就不一樣.
            
            方言
            

            操作系統(tǒng),瀏覽器以及其他軟件供應(yīng)商可用這個(gè)代號(hào)來(lái)提供附加的功能或者到達(dá)語(yǔ)言和國(guó)家代號(hào)所不能實(shí)現(xiàn)的定制.比如說(shuō),一家軟件公司也許會(huì)為一特定操作系統(tǒng)指定一個(gè)locale,于是開(kāi)發(fā)人員為西班牙的Macintosh操作系統(tǒng)創(chuàng)建了es_ES_MAC或者為Windows操作系統(tǒng)創(chuàng)建es_ES_WIN的本地化.
            
            Java平臺(tái)歷史上的一個(gè)例子就是使用EURO變量來(lái)為歐洲用戶實(shí)現(xiàn)本地化.Java 2平臺(tái)1.3標(biāo)準(zhǔn)版過(guò)度時(shí)期里就為歐洲的這些國(guó)家的本地化使用了這個(gè)變量.比如,盡管已經(jīng)存在了 de_DE(德國(guó)德語(yǔ))的本地化,但還是將 de_DE_EURO(歐洲的德國(guó)德語(yǔ))加進(jìn)了Java環(huán)境里.由于歐元是那些接受歐元流通國(guó)家里的標(biāo)準(zhǔn)貨幣,因此這個(gè)變量就從 J2SE1.4版本里剔除了.多數(shù)應(yīng)用程序可能不需要這個(gè)代號(hào).
            
            構(gòu)造
            
            Locale類有如下幾個(gè)構(gòu)造器:
            
            . Locale(String language)
            . Locale(String language, String country)
            . Locale(String language, String country, String variant)
            
            以下展示每個(gè)構(gòu)造器如何使用:
            //創(chuàng)建一個(gè)通用英語(yǔ)的locale.
            Locale locale1 = new Locale("en");
            //創(chuàng)建一個(gè)加拿大英語(yǔ)的locale.
            Locale locale2 = new Locale("en", "CA");
            //創(chuàng)建一個(gè)美式英語(yǔ)的locale
            //硅谷的英語(yǔ)
            Locale locale3 = new Locale("en", "US", "SiliconValley");
            
            用ISO 639的兩字母代號(hào)表示的en代表了英語(yǔ).ISO 3166的代號(hào)CA和US分別代表加拿大和美國(guó).有個(gè)特別:如上代碼片段里最后一行上用一個(gè)可選變量en_US_SiliconValley創(chuàng)建locale.
            
            這個(gè)locale比第一個(gè)locale更明細(xì).不僅說(shuō)明了是美式英語(yǔ),還特地講指出是硅谷那邊的.其目的之一是讓開(kāi)發(fā)者可以定制用戶的本地化,這個(gè)變量可以是任何你想要的值.
            
            雖然編譯與運(yùn)行環(huán)境不關(guān)心你是否指定了你自己的語(yǔ)言或者是別的國(guó)家地區(qū),但是你應(yīng)當(dāng)用ISO標(biāo)準(zhǔn)里定義的代號(hào)來(lái)區(qū)別.強(qiáng)制自己去用ISO標(biāo)準(zhǔn)里的定義,這樣可確保同其他應(yīng)用程序或者代碼標(biāo)準(zhǔn)兼容.
            
            更為重要的一點(diǎn)是,區(qū)域敏感型的類庫(kù)僅用ISO代號(hào).比如,java.text.NumberFormat類對(duì)于de_DE的本地化是能明白的,但是卻不知如何處置虛構(gòu)的foo_biz.假如用非ISO標(biāo)準(zhǔn)的定義,你不得不寫(xiě)程序代碼去實(shí)現(xiàn)支持那些非ISO標(biāo)準(zhǔn)定義的代號(hào).
            
            預(yù)定義的Locale
            
            Locale類里有幾個(gè)Locale類型的靜態(tài)成員實(shí)例.比如說(shuō),Locale.FRANCE 就是預(yù)先就準(zhǔn)備好的代表法國(guó)法語(yǔ).你可在想要的地方用Locale.FRANCE也可以用new Locale("fr", "FR")的方式來(lái)實(shí)現(xiàn).表四給出了一些預(yù)定義的現(xiàn)成Locale對(duì)象實(shí)例
            
            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
            
            這些個(gè)預(yù)定義的Locale對(duì)象的實(shí)例的存在確實(shí)很方便.然而,僅列出的這幾個(gè)靜態(tài)成員是有限的,不完整的,并不需要對(duì)每個(gè)重要的locale都要來(lái)描述.支持區(qū)域敏感型的類的locale并不需要在Locale類里有Locale類型的成員常量.比如說(shuō),Locale類里就沒(méi)有代表南美洲的常量.雖然沒(méi)有,但是照樣支持包括日期格式和數(shù)字格式這樣的區(qū)域敏感型的類.
            
            由于僅存在極少量的預(yù)先準(zhǔn)備好的locale,以至你可能回避這些靜態(tài)實(shí)例.但是確實(shí)存在或者你會(huì)在別人的代碼里碰到,所以在此對(duì)它們有所提級(jí),盡管它們很方便,但是不靠它們,你的代碼也是可行的.
            
            識(shí)別支持的Locales
            
            Java平臺(tái)支持什么樣的locale?你可創(chuàng)建你想要的任何locale,然而你的運(yùn)行時(shí)刻環(huán)境不一定全支持你創(chuàng)建的這些locale.
            
            那么你想知道你可以創(chuàng)建什么樣的locale呢?答案很簡(jiǎn)單:你可創(chuàng)建任何你要的locale.構(gòu)造器不會(huì)在乎非ISO標(biāo)準(zhǔn)的參數(shù).但是從這個(gè)提問(wèn)里引出來(lái):對(duì)什么樣的locale,類庫(kù)能提供更多信息呢?對(duì)什么樣的locale,庫(kù)能提供整理,時(shí)間,日期,數(shù)字和貨幣的信息呢?也許你會(huì)依靠腳本或干脆你來(lái)寫(xiě)能支持運(yùn)行環(huán)境的系統(tǒng).
            
            以下部分講述如何識(shí)別出運(yùn)行庫(kù)能支持的locales.另外還講解了可支持文本組件的書(shū)寫(xiě).最后,例舉了運(yùn)行庫(kù)中和開(kāi)發(fā)包里的幾個(gè)可用的本地化.
            
            把locale用在java.util包和java.text包
            
            運(yùn)行時(shí)刻環(huán)境并不需要對(duì)每個(gè)區(qū)域敏感型的類都要用locale來(lái)支持.每個(gè)區(qū)域敏感型的類實(shí)現(xiàn)為它自身支持的一套locale,這套設(shè)置能使類跟類可區(qū)別開(kāi)來(lái).比如,一個(gè)格式化數(shù)字類支持的locale就跟一個(gè)日期類支持的locale有所區(qū)別.
            
            另外,不需要所有的運(yùn)行環(huán)境的實(shí)現(xiàn)都要支持同一套locale.但是所有的運(yùn)行環(huán)境的實(shí)現(xiàn)都必須支持一個(gè)locale的最小集合.這個(gè)集合很小,僅是英語(yǔ)環(huán)境(U.S).幸好,SUN公司提供的運(yùn)行環(huán)境的實(shí)現(xiàn)里提供了更多的支持.盡管這不是形式上所必須的,但是SUN公司提供的各運(yùn)行環(huán)境的實(shí)現(xiàn)里為區(qū)域敏感型的數(shù)據(jù)格式提供了同樣的一套集合.這樣的做法為類提供了一致性.Java 2標(biāo)準(zhǔn)版5.0里對(duì)locale支持的指南提供了詳細(xì)的列表說(shuō)明.表五給出一部分所支持的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
            
            你得問(wèn)一問(wèn)區(qū)域敏感型的類在運(yùn)行時(shí)刻環(huán)境里(JRE)到底支持什么locales.每個(gè)區(qū)域敏感型類支持通過(guò)實(shí)現(xiàn)方法getAvailableLocales()來(lái)支持多種locale.比如:
            Locale[] localeList = NumberFormat.getAvailableLocales();
            
            java.util和java.text包里有許多類實(shí)現(xiàn)了getAvailableLocales()方法.例如,NumberFormat,
            DateFormat,Calendar和BreakIterator.
            
            Locale類本身也是本本地化成幾個(gè)locale,在下面例子中,一個(gè)德國(guó)locale實(shí)例以英語(yǔ)(默認(rèn)情況下是作者的主機(jī)),德語(yǔ)和法語(yǔ)提供了信息:
            
            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
            
            對(duì)字符的支持
            
            文本組件通常不支持單個(gè)locale.實(shí)際上文本組件常在本地上用一套書(shū)寫(xiě)樣式來(lái)顯示.
            
            盡管不能從各文本組件上獲取一個(gè)所支持的書(shū)寫(xiě)樣式列表,但是這樣的一個(gè)列表卻是J2SE 5.0的本地化指南中公開(kāi)的.
            
            通常,AWT對(duì)等體組件在操作系統(tǒng)的支持下可進(jìn)行書(shū)寫(xiě)樣式的展示.如果你的系統(tǒng)是阿拉伯的環(huán)境,那么AWT的文本組件會(huì)顯示阿拉伯文字.在一個(gè)阿拉伯環(huán)境的系統(tǒng)上,你也能在文本框或者文本域里輸入阿拉伯文.然而你可別指望不在同一語(yǔ)言環(huán)境時(shí)這些AWT組件可顯示同樣的文本.比如在一個(gè)英語(yǔ)環(huán)境的系統(tǒng)不大可能在文本框里顯示阿拉伯文字.
            
            Java Foundation Classes/Swing (JFC/Swing)組件通常能支持多語(yǔ)言,是因?yàn)椴灰蕾囍鳈C(jī)系統(tǒng)以及使用UNICODE作為多語(yǔ)言字符集的編碼.因此SWING組件通常可顯示多語(yǔ)言字符而AWT的對(duì)等體組件就不能.表六顯示了一些能支持的字符
            
            表六.一些可顯示的文本字符
            
            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的本地化
            
            運(yùn)行環(huán)境里的幾個(gè)用戶界面元素已經(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
            
            某些開(kāi)發(fā)工具,比如JAVA編譯器,僅隨J2SE的軟件開(kāi)發(fā)包供給.這些工具為用戶提供了出錯(cuò),出錯(cuò),警告和其他消息.這些工具以及SDK里的實(shí)用工具包括編譯器里的消息,被翻譯為英語(yǔ)或者日語(yǔ).這些翻譯的結(jié)果在J2SE 5.0里已經(jīng)實(shí)現(xiàn)了.
            
            以字符串形式描述locale
            
            盡管你使用locale的多數(shù)時(shí)候需要引用一個(gè)Locale對(duì)象,但是有些時(shí)候用另一種表現(xiàn)形式會(huì)很方便,尤其是進(jìn)行內(nèi)部調(diào)試時(shí)候.Locale對(duì)象的toString()方法返回String,它是語(yǔ)言,區(qū)域和變種代號(hào)的一個(gè)串.toString()方法以下劃線來(lái)把各部分隔開(kāi).這樣,提供了一種方便的可讀性好的形式方便你的調(diào)試.
            
            考慮如下那樣創(chuàng)建locale的代碼
            Locale l = new Locale("ja", "JP");
            
            toString()方法將返回 "ja_JP".
            
            如此的字符串不適合提供給最終用戶.大多數(shù)用戶不熟悉ISO 639和ISO 3166標(biāo)準(zhǔn)中的國(guó)家和語(yǔ)言的代號(hào),會(huì)覺(jué)得這樣的字符串不好懂.幸好還有友好用戶界面的文本展示,我們將在本文后面中討論.
            
            使用locale
            
            盡管不常見(jiàn),Locale對(duì)象卻是在JAVA類庫(kù)中普遍用到.即使你不明確地要求用locale,JAVA運(yùn)行環(huán)境也會(huì)為你提供缺省的設(shè)置來(lái)實(shí)現(xiàn)消息和行為的本地化.當(dāng)你明確地使用locale,你可為你的應(yīng)用程序的每個(gè)部分使用不同的locale.
            
            譬如,你可用es_MX,西班牙語(yǔ)(墨西哥)的locale來(lái)顯示本地化的消息;用en_US,(美式英語(yǔ))的locale來(lái)顯示貨幣和數(shù)字.這方式很適合在美國(guó)工作生活的習(xí)慣西班牙語(yǔ)的人.盡管用戶見(jiàn)到的是西班牙語(yǔ)的菜單,提示與文本,但是應(yīng)用程序其他地方可見(jiàn)到按照美國(guó)習(xí)慣的貨幣和數(shù)字.這個(gè)簡(jiǎn)單例子向你展現(xiàn)了如何在一個(gè)應(yīng)用程序里使用多種locale.如果你的應(yīng)用程序真是需要這樣的locale支持的話,那么你可自主決定應(yīng)用程序各方面的行為.
            
            除了像格式化數(shù)字,貨幣,日期和時(shí)間這樣的區(qū)域敏感型的類之外還提供了如同詞語(yǔ)分解的整理功能.
            
            這些類通常以構(gòu)造器或者是工廠方法來(lái)實(shí)例化.無(wú)論哪種形式,你可按照你喜歡的一種來(lái)創(chuàng)建一個(gè)詳細(xì)的locale.
            
            使用缺省Locale
            
            無(wú)論應(yīng)用程序是否明確指定了詳細(xì)的locale,區(qū)域敏感型的對(duì)象都會(huì)選用缺省的locale.依賴這缺省的locale很不明智.在多用戶應(yīng)用程序里,不是每個(gè)用戶都適合這個(gè)缺省的locale,因此應(yīng)用程序應(yīng)當(dāng)為所有的區(qū)域敏感型對(duì)象明確指定一個(gè)適合的locale.缺省的locale是一種為應(yīng)用程序里所有的區(qū)域敏感型對(duì)象提供的系統(tǒng)資源.缺省時(shí),也許對(duì)用戶來(lái)說(shuō)可能是對(duì)的,但是應(yīng)當(dāng)在多語(yǔ)言和多文化的環(huán)境下明確指定,當(dāng)程序運(yùn)行在一臺(tái)機(jī)器上為多用戶所使用時(shí),這點(diǎn)尤其重要.
            
            用如下的方法來(lái)獲得缺省locale:
            public static Locale getDefault()
            
            有三種途徑為應(yīng)用程序確定出一個(gè)缺省的locale.
            
            第一,除非明確的更改默認(rèn)的locale,否則getDefault()方法返回值的locale是由JAVA虛擬機(jī)首次裝載時(shí)確定的.這就是說(shuō),JAVA虛擬機(jī)從系統(tǒng)環(huán)境確定出了缺省的locale.系統(tǒng)環(huán)境上的locale是由操作系統(tǒng)和用戶喜好來(lái)確定的;
            
            第二,某些JAVA運(yùn)行環(huán)境的實(shí)現(xiàn)里,用戶可通過(guò)命令行上設(shè)置user.language, user.country以及 user.variant信息來(lái)覆蓋掉系統(tǒng)的缺省locale.
            
            如的代碼會(huì)依據(jù)這些設(shè)置的屬性來(lái)打印出locale
            import java.util.Locale;
            
            public class Default {
            public static void main(String[] args) {
            System.out.println(Locale.getDefault());
            }
            }
            
            根據(jù)如上代碼來(lái)做個(gè)實(shí)驗(yàn).運(yùn)行在U.S的英語(yǔ)系統(tǒng)時(shí)候,如上代碼會(huì)輸出en_US. 假如在命令行上給出選項(xiàng)參數(shù),那么你可讓程序使用任何你想要的locale.例如,為程序提供如下的命令行參數(shù):
            java -Duser.language=fr -Duser.country=CA Default
            
            以這樣的方式來(lái)運(yùn)行程序的話,將把fr_CA當(dāng)作默認(rèn)的locale
            
            第三,可通過(guò)調(diào)用setDefault(Locale aLocale)方法來(lái)實(shí)現(xiàn). setDefault(Locale aLocale)方法讓?xiě)?yīng)用程序設(shè)置了一個(gè)系統(tǒng)級(jí)別的資源.在用此方法設(shè)置了缺省的locale后,接著調(diào)用Locale.getDefault()就得到了最新設(shè)置的locale.
            
            注意:別在applet中調(diào)用setDefault()方法.applet的安全管理不會(huì)讓你調(diào)用這方法的,因?yàn)檫@個(gè)方法調(diào)用的結(jié)果會(huì)影響主機(jī)上運(yùn)行著的JAVA虛擬機(jī)上的系統(tǒng)級(jí)別的資源.
            
            大多數(shù)情況下,對(duì)于其他類使用缺省locale意味著完全忽略locale.譬如,你想要以缺省locale格式化一個(gè)數(shù)字,你可以簡(jiǎn)單地而不需要任何參數(shù)來(lái)創(chuàng)建NumberFormat:
            NumberFormat nf = NumberFormat.getInstance();
            
            如上代碼的情況下使用locale基本上不需要你做什么.另外一些區(qū)域敏感型的類也是照這樣的模式.需要缺省locale的行為的時(shí)候不需要作特定的工作來(lái)創(chuàng)建.但是缺省行為不是適合所有情況的,因此在特殊時(shí)候你還需要明確指定locale.
            
            顯示使用locale
            
            在有些計(jì)算機(jī)的環(huán)境中,僅有單一的locale貫穿于整個(gè)應(yīng)用程序的生命周期里.另外一些環(huán)境里,應(yīng)用程序使用一個(gè)可變的全局locale.在這些環(huán)境里,你可通過(guò)編程來(lái)改變locale,除非去改動(dòng)locale,否則它一直保持原先的效果.JAVA應(yīng)用程序環(huán)境很獨(dú)特,在應(yīng)用程序里,可依照你想要的任何方式來(lái)使用不同的locale.
            
            跨國(guó)公司在世界上有許多客戶.這就意味著這些公司的客戶和員工也許使用著不同的語(yǔ)言并且希望公司和公司的軟件能適合他們.此外,很可能也很常見(jiàn)的事是:公司里有個(gè)法國(guó)雇員為一位意大利客戶處理銷(xiāo)售記錄.在這種情形下,你必須要控制好業(yè)務(wù)以及用戶界面中的對(duì)象所使用的locale以便處理和展現(xiàn)數(shù)據(jù).應(yīng)用程序可能在打印銷(xiāo)售收據(jù)時(shí)候使用意大利格式的日期和貨幣格式,然而又要為習(xí)慣英語(yǔ)的雇員列客戶清單.還有很多類似這么復(fù)雜的情況沒(méi)有列在此處.但是JAVA技術(shù)提供了靈活的方式來(lái)處理如此復(fù)雜的情況.
            
            為了最大限度的靈活性,你必須為區(qū)域敏感型的類指定明確的locale.這就意味著你必須為程序的各個(gè)方面考慮locale的表現(xiàn)樣式或者為不同的用戶和客戶指定locale.
            
            如果你已經(jīng)為用戶方的locale作了考慮,那么在構(gòu)造器參數(shù)列表里明確指定一個(gè)locale或者在一些特定方法里指定以此來(lái)創(chuàng)建區(qū)域敏感型的類的實(shí)例.設(shè)想有個(gè)用來(lái)作展現(xiàn)的對(duì)象里存儲(chǔ)了為客戶選用的locale:
            
            Locale userLocale = preferences.getLocale();
            NumberFormat nf = NumberFormat.getInstance(userLocale);
            
            獲取locale的信息
            
            由于locale對(duì)象不包含很多信息,但是提供了一些有趣的方法.正如你想的,這些信息跟語(yǔ)言,國(guó)家和方言是有密切聯(lián)系的.其中一些是依賴locale的,另一些則不依賴locale.這些情況說(shuō)明了locale對(duì)象為它的方法提供了兩種不同形式.locale里的一些信息并非是面向客戶或者本地化的,另一些則是本地化的并且適合用來(lái)為用戶展現(xiàn)的.
            
            不依賴locale的信息
            
            getLanguage() 方法返回ISO 639 標(biāo)準(zhǔn)中為語(yǔ)言定義的兩字母縮寫(xiě).比如,你創(chuàng)建了ja_JP的locale,那么方法返回的是 ja . 這個(gè)方法的完整形式是:
            
            public String getLanguage()
            
            ISO 639標(biāo)準(zhǔn)的一個(gè)擴(kuò)展是用三個(gè)字母縮寫(xiě)的代號(hào)來(lái)定義語(yǔ)言的.盡管在J2SE 5.0里不使用這些代號(hào),但是卻是有用的.用如下的方法來(lái)獲得三字母縮寫(xiě)的語(yǔ)言代號(hào):
            
            public String getISO3Language()
            
            看個(gè)對(duì)比的例子:
            
            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)中兩字母縮寫(xiě)定義的國(guó)家或者區(qū)域代號(hào).方法的完整形式: public String getCountry()
            
            也有個(gè)ISO擴(kuò)展標(biāo)準(zhǔn)里用三字母縮寫(xiě)來(lái)定義國(guó)家代號(hào):public String getISO3Country()
            
            看個(gè)對(duì)比的例子:
            
            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對(duì)象里設(shè)置有方言的字段的話, getVariant()方法返回一個(gè)字符串來(lái)表示.如果locale對(duì)象里沒(méi)設(shè)置方言的字段的話,此方法返回空串.此方法的形式如下:public String getVariant()
            
            locale類中的如下幾個(gè)方法可獲取所有可用的語(yǔ)言代號(hào)和國(guó)家代號(hào):
            public static String[] getISOCountries()
            public static String[] getISOLanguages()
            
            相對(duì)于客戶來(lái)說(shuō),開(kāi)發(fā)者更愿意使用getLanguage()方法返回的代號(hào).而客戶可能想要如下文中描述的那些不同之處.
            
            依賴locale的信息
            
            方法getLanguage(), getCountry(), getVariant()返回的代號(hào)對(duì)于用戶來(lái)說(shuō)不友好.用戶并不需要懂這些代號(hào),因此locale提供另外的一些方法來(lái)提供了更具有可讀性的面向客戶的信息.
            
            locale對(duì)象提供了一些可返回人能讀懂的文本描述的方法.這些文本描述不同于toString()方法返回的字符串.并非把語(yǔ)言,國(guó)家和方言這些字段簡(jiǎn)單的串連起來(lái),而是提供了locale的人可讀懂的,本土化了的信息:
            
            public final String getDisplayLanguage()
            public final String getDisplayCountry()
            public final String getDisplayVariant()
            
            顯示語(yǔ)言
            
            當(dāng)你需要以用戶習(xí)慣的語(yǔ)言來(lái)顯示的時(shí)候,應(yīng)使用locale對(duì)象的getDisplayLanguage()放.此方法返回了可顯示的,人能讀懂的用戶方語(yǔ)言的名稱.假如你不給出目標(biāo)locale的話,這個(gè)顯示的名稱就是缺省的locale的本土化.此方法的兩種形式:
            public final String getDisplayLanguage()
            public final String getDisplayLanguage(Locale targetLocale)
            
            以下舉例如何使用這兩個(gè)方法:
            
            Locale deLocale = Locale.GERMANY;
            // 系統(tǒng)默認(rèn)的locale是 en_US
            String defaultLanguage = deLocale.getDisplayLanguage();
            //目標(biāo)locale顯示地指出了使用的語(yǔ)言
            String targetLanguage = deLocale.getDisplayLanguage(deLocale);
            System.out.println(defaultLanguage);
            System.out.println(targetLanguage);
            
            輸出結(jié)果如下:
            German
            Deutsch
            
            輸出的 German 是以美式英語(yǔ)單詞來(lái)顯示locale里所使用的語(yǔ)言.這并沒(méi)給你留下特別的印象,但是要注意的是:你怎樣提供一個(gè)目標(biāo)locale作參數(shù).這種情形中,getDisplayLanguage()試圖找到和返回一個(gè)本土化了的lcoale中語(yǔ)言組件的版本.
            
            這一點(diǎn)很重要,因?yàn)槟隳転榭蛻麸@示應(yīng)用程序可支持的客戶方語(yǔ)言的每個(gè)locale的語(yǔ)言名稱.你可在程序里提供一個(gè)列表來(lái)讓用戶選他們喜好的locale.
            
            這就引來(lái)一個(gè)有趣的問(wèn)題:如何在locale的語(yǔ)言環(huán)境里呈現(xiàn)locale的語(yǔ)言名稱?你可按照如下代碼來(lái)做:
            String displayLang = aLocale.getDisplayLanguage(aLocale);
            
            換言之,就是在調(diào)用getDisplayLanguage()方法時(shí)候以此locale對(duì)象作參數(shù).對(duì)于其他可顯示的locale元素也可使用這個(gè)竅門(mén).比如,也能用這種方法來(lái)顯示國(guó)家和方言.如下代碼演示了這個(gè)竅門(mén).
            
            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);
            }
            
            顯示國(guó)家
            
            給用戶顯示locale對(duì)象里的國(guó)家或者地區(qū)信息時(shí)可按照如下代碼:
            
            public final String getDisplayCountry()
            public final String getDisplayCountry(Locale targetLocale)
            
            第一種形式的方法為缺省locale提供了本土化的國(guó)家名稱.第二種形式的方法為目標(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里相對(duì)于其他元素用地比較少.然而有時(shí)還需要要獲取它的信息.
            
            getDisplayVariant()方法返回locale里的方言部分的顯示名稱.
            
            public final String getDisplayVariant()
            public final String getDisplayVariant(Locale targetLocale)
            
            在JAVA平臺(tái)使用方言的一個(gè)方法是為支持泰國(guó)語(yǔ)言.根據(jù)約定,對(duì)于 th 和 th_TH的locale而使用的NumberFormat對(duì)象通常以阿拉伯?dāng)?shù)字或者是泰國(guó)格式的阿拉伯?dāng)?shù)字來(lái)使用.對(duì)于th_TH_TH的locale的NumberFormat是用泰國(guó)數(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");
            }
            
            顯示名稱
            
            顯示名稱僅是簡(jiǎn)單地組合了本土化語(yǔ)言,國(guó)家和剛才演示的方言.方法的形式如下:
            public final String getDisplayName()
            public final String getDisplayName(Locale targetLocale)
            
            跟locale的toString()方法有所不同.toString()方法是串聯(lián)起來(lái)各個(gè)部分并且以下劃線分割.
            getDisplayName()方法以括號(hào)分割各個(gè)部分.
            
            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是一門(mén)語(yǔ)言,一個(gè)可選國(guó)家(或者一個(gè)地區(qū))或者是一個(gè)可選方言代號(hào)的標(biāo)識(shí)符.locale對(duì)象提供了幾個(gè)方法來(lái)獲取關(guān)于locale狀態(tài)的信息.盡管locale本身不包含許多功能,但是區(qū)域敏感型對(duì)象依賴于locale來(lái)指示行為.區(qū)域敏感型對(duì)象用locale來(lái)定制它們的行為以此滿足用戶所想要的.
            
            JAVA平臺(tái)上,每個(gè)區(qū)域敏感型對(duì)象負(fù)責(zé)它自身區(qū)域相關(guān)的行為.設(shè)計(jì)上,區(qū)域敏感型對(duì)象之間互不相干.這就是說(shuō),在一個(gè)類里被支持的locale并不一定要跟另一個(gè)類里被支持的lcoale一樣.
            
            在傳統(tǒng)的操作系統(tǒng)上和區(qū)域模型里,在同一時(shí)間里僅有一個(gè)locale的設(shè)置起作用.這些系統(tǒng)上,在你通過(guò)編程來(lái)設(shè)置locale后,所有的區(qū)域敏感型的功能都會(huì)使用指定的locale,這個(gè)locale猶如一個(gè)全局locale一樣貫穿于應(yīng)用程序.當(dāng)以setLocale方法或者類似的調(diào)用使另一個(gè)全局locale起作用后才發(fā)生改變.JAVA平臺(tái)上,由于處理locale時(shí)有些不同,所以一個(gè)JAVA應(yīng)用程序里在同一時(shí)間可有多個(gè)locale起作用.配合格式對(duì)象使用多種loalce讓開(kāi)發(fā)者有機(jī)會(huì)為多語(yǔ)言和多文化環(huán)境的應(yīng)用程序創(chuàng)建復(fù)雜的必要的組合.

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          posts - 26, comments - 5, trackbacks - 0, articles - 8

          Copyright © 負(fù)人博客

          主站蜘蛛池模板: 定安县| 敦化市| 滦南县| 安吉县| 泽州县| 富宁县| 淮滨县| 库伦旗| 贺州市| 安塞县| 赤峰市| 恭城| 勃利县| 屯留县| 新竹县| 陕西省| 阳春市| 宜阳县| 当涂县| 凉城县| 出国| 崇州市| 兖州市| 旅游| 正阳县| 怀来县| 花垣县| 盘锦市| 勐海县| 安泽县| 略阳县| 巴林右旗| 呼图壁县| 砀山县| 合江县| 纳雍县| 抚宁县| 多伦县| 高尔夫| 玉田县| 和田市|