java基礎---->java中國際化的實現

 

  應用程序的功能和代碼設計考慮在不一樣地區運行的須要,其代碼簡化了不一樣本地版本的生產。開發這樣的程序的過程,就稱爲國際化。今天,咱們就開始學習java中國際化的代碼實現。java

 

Java國際化主要經過以下3個類完成數組

  • java.util.ResourceBundle:用於加載一個資源包
  • java.util.Locale:對應一個特定的國家/區域、語言環境。
  • java.text.MessageFormat:用於將消息格式化

爲實現程序的國際化,必須提供程序所須要的資源文件。資源文件的內容由key-value對組成。資源文件的命名能夠有3種格式:ide

  • basename_language_country.properties
  • basename_language.properties
  • basename_properties

 

java se中國際化的實現

java se的國際化實現,項目結構以下:學習

首先定義屬性文件,它的命名規則見上述。具體代碼ResourceBundleTest.java以下測試

1、獲得全部可用的Locale,結果太長就不列出了,一共156列

public static void getLocales() { Locale[] availableLocales = Locale.getAvailableLocales(); System.out.println(availableLocales.length); for (Locale locale : availableLocales) { System.out.println(locale.toString()); } }

 

2、 使用系統默認的Locale

public static void useDefaultLocale() { ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.myres"); String string = resourceBundle.getString("name"); System.out.println(string); }

ResourceBundle.getBundle("locale.myres")與ResourceBundle.getBundle("locale.myres", Locale.getDefault())同樣。ui

 

3、 使用本身指定的Locale

public static void useOwnLocale() { Locale locale = new Locale("zh", "CN"); ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.myres", locale); String string = resourceBundle.getString("name"); System.out.println(string); }

 

4、 使用帶佔位符的消息

public static void getMessage() { ResourceBundle resourceBundle = ResourceBundle.getBundle("locale/myres"); String message = resourceBundle.getString("message"); System.out.println(MessageFormat.format(message, "huhx", "劉力")); }

myres_zh_CN.properties文件中有:this

message=My name is {0}—, and I love you. --{1}

打印結果: My name is huhx—, and I love you. --劉力spa

 

5、 使用類文件代替資源文件

Java容許使用類文件來代替資源文件,即手動書寫代碼來實現國際化,設計

  • 該類要求繼承於ListResourceBundle,並重寫getContents方法該方法返回Object數組,該數組的每個項都是key-value對。
  • 類的名字必須爲basename_language_contry,這與屬性文件的命名類似

在locale包下增長myres_zh_CN.java類,內容以下:code

package locale; import java.util.ListResourceBundle; public class myres_zh_CN extends ListResourceBundle { private final Object myData[][] = { { "message", "Hello, {0} and {1}" }, { "test", "test" } }; @Override protected Object[][] getContents() { return myData; } }

在Main中的測試使用代碼:

public static void getMessage() { ResourceBundle resourceBundle = ResourceBundle.getBundle("locale.myres"); String message = resourceBundle.getString("message"); System.out.println(MessageFormat.format(message, "huhx", "劉力")); }

打印結果:Hello, huhx and 劉力

注意:若是系統同時存在資源文件、類文件,系統將以類文件爲主,而不會調用資源文件。例如對於basename爲myres的這一系列中文資源文件,系統搜索順序以下

  1. myres_zh_CN.java
  2. myres_zh_CN.properties
  3. myres_zh.java
  4. myres_zh.properties
  5. myres.java
  6. myres.properties

若是getBundle的參數是「locale/myres」,那麼位於locale的對應類就不會去查找,只會去查找屬性文件。只有「locale.myres」纔會先查找類,再查找屬性文件

 

6、咱們看一下ResourceBundle的getString(key)方法的源碼,其實是調用getObject(key)方法

public final Object getObject(String key) { Object obj = handleGetObject(key); if (obj == null) { if (parent != null) { obj = parent.getObject(key); } if (obj == null) throw new MissingResourceException("Can't find resource for bundle " +this.getClass().getName() +", key "+key, this.getClass().getName(), key); } return obj; }

首先會調用handleGetObject方法,代碼以下:

public final Object handleGetObject(String key) { // lazily load the lookup hashtable. if (lookup == null) { loadLookup(); } if (key == null) { throw new NullPointerException(); } return lookup.get(key); // this class ignores locales }

lookup是Map<String,Object>,聲明爲空。執行loadLookup()方法

private synchronized void loadLookup() { if (lookup != null) return; Object[][] contents = getContents(); HashMap<String,Object> temp = new HashMap<>(contents.length); for (int i = 0; i < contents.length; ++i) { // key must be non-null String, value must be non-null String key = (String) contents[i][0]; Object value = contents[i][1]; if (key == null || value == null) { throw new NullPointerException(); } temp.put(key, value); } lookup = temp; }

執行ListResourceBundle的getContens()方法,將返回的結果有規律的對應鍵值對存放在map中。

If ListResourceBundle or PropertyResourceBundle do not suit your needs, you can write your own ResourceBundle subclass. Your subclasses must override two methods: handleGetObject and getKeys(). 

 


出處: www.cnblogs.com/huhx
相關文章
相關標籤/搜索