2016-04-02 2 views
1

Я видел этот код из учебника Java Oracle, и я смущен относительно того, как он на самом деле работает. У меня есть несколько вопросов, на которые я надеюсь, что кто-то может любезно помочь мне ответитьнеспособный понять java учебник oracle интернационализация Настройка ресурса Bundle Пример загрузки

1) Я не вижу, что public List<Locale> getCandidateLocales(String baseName, Locale locale) был вызван из любого места, так как он фактически выполняется?

2) то, что передается в качестве аргументов public List<Locale> getCandidateLocales(String baseName, Locale locale)

3) public List<Locale> getCandidateLocales(String baseName, Locale locale) возвращает List<Locale>, что цель возвращения List<Locale>

4) public List<Locale> getCandidateLocales(String baseName, Locale locale) возвращение super.getCandidateLocales(baseName, locale);, если ни один из, если заявление удовлетворено, который это класс, к которому относится ключевое слово super?

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). В более старых версиях Java это будет всего лишь Locale.getDefault(). В веб-приложении решение фактически зависит как от технологии (т. Е. От Spring, JSF, Thymeleaf, Play, ...), так и от вашего подхода к локальному обнаружению. В любом случае, вы должны сначала попробовать наиболее специализированный, чем отступить. Например, французский канадский пользователь (языковой тег fr-CA) должен был видеть содержимое messages_fr_CA.properties, тогда как другим пользователям французского языка следует подавать содержимое messages_fr.properties. Аналогичным образом, любой другой язык должен соблюдать переводы, сделанные от messages.properties.
    Что делает этот метод, он будет генерировать резервные локали для пользователя (т. Е. Для ввода Locale.forLanguageTag("fr-CA") он вернет сам вход, французский язык («fr») и неопределенный указатель локали («und»). один говорит ResourceBundle использовать файл по умолчанию

  3. Он возвращает список резервных районов, как я уже говорил выше

  4. Он вызывает метод в родительском классе -... ResourceBundle.Control анонимный внутренний класс, определенный в приведенный вами код фактически получен от ResourceBundle.Control.

+0

Большое спасибо за подробное объяснение! это больше, чем я когда-либо надеялся!Кстати, я был заинтригован вашим комментарием, что этот стиль кода предшествует java7. Я сам не придумал код, я нашел его на Java-учебнике Oracle. Значит ли это, что Oracle Tutorials устарели? – Thor

+1

@ Тони: Ну, к сожалению, требуется время, чтобы поддерживать актуальность, поэтому я думаю, что ответ в какой-то степени да. Код по-прежнему работает, но есть вещи, которые нуждаются в обновлении, т. Е. 'Objects.requireNonNull (basename);' вместо ручной проверки на нуль и 'Locale.forLanguageTag (" zh-HK ")' вместо прямого вызова конструктора. Последнее может быть спорным. –