2016-04-02 2 views
1

このチュートリアルはJavaチュートリアルのOracleから見ましたが、実際にどのように動作するのか混乱しています。私は誰かが私に助けてくれることを願っているいくつかの質問を持っていますjavaチュートリアルoracleの国際化を理解できませんリソースバンドルのロードの例をカスタマイズする

1)私はpublic List<Locale> getCandidateLocales(String baseName, Locale locale)がどこから呼ばれたのか分かりません。 List<Locale>を返しpublic List<Locale> getCandidateLocales(String baseName, Locale locale)public List<Locale> getCandidateLocales(String baseName, Locale locale)

3)に引数として渡されるもの

2)、のいずれも文が満たされた場合、どの場合List<Locale>

4)public List<Locale> getCandidateLocales(String baseName, Locale locale)リターンsuper.getCandidateLocales(baseName, locale);を返す目的は何ですキーワードスーパーが参照するクラスですか?

public class RBControl { 
    public static void main(String[] args) { 
    test(Locale.CHINA); 
    test(new Locale("zh", "HK")); 
    test(Locale.TAIWAN); 
    test(Locale.CANADA); 
    } 

    private static void test(Locale locale) { 
    ResourceBundle rb = ResourceBundle.getBundle("Internationalisation/RBControl", locale, 
     new ResourceBundle.Control() { 
     @Override 
     public List<Locale> getCandidateLocales(String baseName, Locale locale) { 
      if (baseName == null) 
      throw new NullPointerException(); 
      if (locale.equals(new Locale("zh", "HK"))) { 
      return Arrays.asList(
       locale, 
       Locale.TAIWAN, 
       // no Locale.CHINESE here 
       Locale.ROOT); 
      } else if (locale.equals(Locale.TAIWAN)) { 
      return Arrays.asList(
       locale, 
       // no Locale.CHINESE here 
       Locale.ROOT); 
      } 
      return super.getCandidateLocales(baseName, locale); 
     } 
     }); 
    System.out.println("locale: " + locale); 
    System.out.println("\tregion: " + rb.getString("region")); 
    System.out.println("\tlanguage: " + rb.getString("language")); 
    } 
} 

ありがとうございました!

答えて

1

正直なところ、あなたのコードスタイルがJava 7よりも前になっているので(あなたは考古学者ですか?)、私は試してみます。

  1. 私はコードのみからテキストリソースをロードするために有効なファイル名またはクラス名を検索したときgetCandidateLocales(String, String)が実際に呼び出されることを保証することができます。例:

    // ResourceBundle.java line 1314 
    private static ResourceBundle getBundleImpl(String baseName, Locale locale, 
                  ClassLoader loader, Control control) { 
        // (...) many lines removed 
        // line 1352 - loop through files to find the best one 
        ResourceBundle baseBundle = null; 
        for (Locale targetLocale = locale; 
         targetLocale != null; 
         targetLocale = control.getFallbackLocale(baseName, targetLocale)) { 
         // line 1356, there you are 
         List<Locale> candidateLocales = control.getCandidateLocales(baseName, targetLocale); 
         if (!isKnownControl && !checkList(candidateLocales)) { 
          throw new IllegalArgumentException("Invalid Control: getCandidateLocales"); 
         } 
    
         bundle = findBundle(cacheKey, candidateLocales, formats, 0, control, baseBundle); 
    
         // lengthy comment removed for clarity 
         if (isValidBundle(bundle)) { 
          // checking if it is the right one, removed 
         } 
        } 
    
        // logic to deal with missing file, removed  
        return bundle; 
    } 
    
  2. 私はそれが今明らかであると信じていますが、詳細に行きます。あなたのメッセージは、messages.properties - 基本言語、デフォルト言語リソース、messages_fr.properties - フランス語ベースのリソース、messages_fr_CA.properties - フランス語カナダのリソース、そして最後にmessages_de.proprties - ドイツ語のリソースのプロパティファイルの形式であるとします。ベース名は基本ファイル名、つまりmessagesと推測されます。候補ロケールはユーザーインターフェイスロケールです。
    デスクトップアプリケーション(非常にありそうもない)またはモバイルアプリケーションで作業している場合は、Locale.getDetault(Locale.Category.DISPLAY)を呼び出すだけでUIロケールを取得できます。古いバージョンのJavaでは、ちょうどLocale.getDefault()になります。 Webアプリケーションでは、ソリューションは実際にはテクノロジー(つまりSpring、JSF、Thymeleaf、Playなど)とロケール検出のアプローチの両方に依存します。とにかく、転倒よりもまず専門的なものを試してみるべきです。たとえば、フランス語のカナダユーザー(言語タグfr-CA)はmessages_fr_CA.propertiesの内容を見ているは​​ずですが、フランス語のユーザーはmessages_fr.propertiesという内容で表示されます。他のロケールと同様に、messages.propertiesから取られた翻訳を観察する必要があります。
    このメソッドは、ユーザーのフォールバックロケールを生成します(入力Locale.forLanguageTag("fr-CA")の場合、入力自体、フランス語ロケール(fr))、未定義ロケールマーカー( "und")を返します。 。私は前述したように1は、デフォルトのファイルを使用するようにResourceBundleを伝え

  3. それは、フォールバックロケールのリストを返します

  4. それは親クラスのメソッドを呼び出します - 。。ResourceBundle.Controlをで定義された匿名の内部クラスあなたが添付したコードは実際にはResourceBundle.Controlに由来します。

+0

詳しい説明はありがとうございます!それは私がこれまでに望んでいた以上のものです!btw、私はこのコードスタイルがjava7に先立つというあなたのコメントに興味を持っていました。私は自分自身でコードを思い付くことはなかった、私は実際にJavaのチュートリアルOracleでそれを見つけた。つまり、Oracleチュートリアルは期限切れですか? – Thor

+1

@トニー:残念なことに、残念ながら最新のものを保つには時間がかかるので、答えはある程度あると思います。このコードはまだ動作しますが、手動ヌルチェックの代わりに 'Objects.requireNonNull(basename);'とコンストラクタを直接呼び出す代わりに 'Locale.forLanguageTag(" zh-HK ")'が必要です。後者は議論の余地があるかもしれない。 –

関連する問題