國際化: 理解Java平臺上的Locale

          Posted on 2006-07-06 17:48 負人博客 閱讀(261) 評論(0)  編輯  收藏 所屬分類: JAVA技術
          語言和地理環境對我們的文化產生重要影響.我們同他人之間的交流以及生活中的事件都發生在語言和地理環境所產生的一個系統里.由于語言和環境的不同,以至需要我們來制定一個適合的方式來達到向他人表述我們自己或者我們的想法的目的.為了有效地與他人交流,需要考慮對方的文化,環境以及使用對方的語言.
            
            類似地,一套有實效的軟件系統也要考慮用戶的語言和地理區域.語言和區域形成了本地環境,描述了軟件本地化的配置和上下文.在Java平臺上,通過java.util.Locale對象來描述本地化.
            
            本文為在Java平臺上的編程人員講解Locale對象以其含義.
            
            本文分成如下幾部分:
            
            . 定義
            . 構造
            . 預先準備的各Locale
            . 識別可支持的Locale
            . 以字符串來表述Locale
            . 使用 Locale
            . 獲取Locale的信息
            . 總結
            
            定義
            
            Locale確定了一種專門的語言和區域.通過使用java.util.Locale對象來為那些區域敏感型的對象定制格式化數據以及向用戶的展示.Locale影響到用戶界面的語言,情形映射,整理(排序),日期和時間的格式以及貨幣格式.Locale在很多文化背景和語言敏感型的數據操作上的要求很嚴格.
            
            java.util.Locale是個輕量級對象,包含為數不多的幾個重要成員:
            
            . 一個語言代號
            . 一個國家或者區域的可選項
            . 一個另一形式代號的可選項
            
            談到或者書寫Locale時,為了方便使用,可用縮寫.在這樣的縮寫表述里,使用下劃線來把Locale對象的每部分隔開來:
            <language code>[_<country code>[_<variant code>]]
            
            這三部分內容提供了足夠的信息讓其他些個區域敏感型對象為了特定的語言文化來修飾它們的行為.舉例講,java.text.NumberFormat對象格式化出來的數字同在德語拼寫的奧地利和瑞士是有區別的.
            
            表一,不同Locale的格式化輸出
            
            Locale          formatted Numbers
            ======================================
            German (Germany)      123.456,789
            German (Switzerland)    123'456.789
            English (United States)  123,456.789
            
            Locale對象是個標識符,像jva.text.NumberFormat,java.text.DateFormat這樣的區域敏感型的對象都會提供本地化的數字或者日期的格式.舉例說,java.text.DateFormat類在其實例化過程中用Locale對象來正確地定出日期的格式.
            
            以下部分講述locale的各成分
            
            ISO 639制定了語言代號,國際標準組織為世界上的大多數語言指派2個或者3個字母來代表.Locale用2個字母代號標識出想要的語言.表二列出這樣的幾個語言代號.
            
            表二, ISO 639標準里的語言代號的例子
            
            Language   Code
            =====================
            Arabic    ar
            German    de
            English    en
            Spanish    es
            Japanese   ja
            Hebrew    he
            
            語言環境是Locale對象里的重要組成部分,因為它描述了特定用戶群的語言.你的應用程序需要用這此信息來為用戶提供與其語言一致的用戶界面.
            
            當然,語言并沒描繪了整個Locale.舉一例,即使把 de 作為本地語言代號, 單單的一個 de 并不能讓你知道到底是哪一地區的的人講的德語.一些國家把德語作為官方語言或者作為第二種語言.一個國家與另一個國家里的德語的區別之一就是排列順序.由于這樣的原因以及另外些原由,語言并不總能充分地準確地定義一個區域.
            
            國家(區域)代號
            
            另一個國際標準ISO 3166定義了國家代號.這個標準為世界上的大多數主要區域以及每個國家定義了2到3個的縮寫字母.跟語言代號對比,國家代號是用大寫字符的.表三給出了一些代號定義.Locale用兩字母的代號來替代標準里也同樣支持的3字母的代號
            
            表三,ISO 3166標準中的一些國家代號的定義
            
            Country   Code
            ====================
            China      CH
            Canada       CA
            France       FR
            Japan       JP
            Germany   DE
            
            國家代號是Locale的重要組成部分.對應日期的java.text.Format對象,時間,數字和貨幣都對國家代號很敏感.有了國家代號就可更好地確認Locale里的語言部分.舉例來說,在加拿大和法國都說法語的,然而確切的用法和語言表達習慣卻是不一樣的.這些不同之處可以用Locale里的國家代號來區分出來.例如, 代號fr_CA(加拿大法語)跟fr_FR(法國法語)就不一樣.
            
            方言
            

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

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

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

          Copyright © 負人博客

          主站蜘蛛池模板: 金阳县| 浠水县| 巩留县| 北安市| 新野县| 新平| 乌鲁木齐市| 疏附县| 庄浪县| 湘乡市| 旺苍县| 红桥区| 建平县| 上高县| 临桂县| 桂东县| 壤塘县| 太保市| 靖宇县| 巨鹿县| 和平区| 新源县| 宁明县| 金溪县| 会昌县| 衡水市| 阿拉尔市| 中江县| 宜都市| 奈曼旗| 石泉县| 株洲市| 磐石市| 平江县| 轮台县| 农安县| 文登市| 五指山市| 桐城市| 邓州市| 班玛县|