Локализация - Вопросы

Всего: 12 вопросов

1. 

Что такое i18n и l10n и как расшифровываются эти сокращения?

i18n — сокращение слова internationalization (интернационализация): первая буква i, последняя n и 18 букв между ними. l10n так же сокращает localization (локализация): l, 10 букв, n. Такие сокращения называют нумеронимами.

  • Интернационализация — проектирование приложения так, чтобы для нового языка не нужно было перекомпилировать и пересобирать его: тексты хранятся в файлах свойств, а форматы чисел, дат и валют берутся из локали.
  • Локализация — адаптация приложения к конкретному языку и региону: перевод интерфейса и документации, настройка форматов дат, валют и чисел.
  • g11n (globalization) — i18n и l10n вместе; L10n с заглавной L пишут, чтобы букву не путали с цифрой 1.

В Java обе задачи связывает локаль — объект java.util.Locale, пара «язык + регион», например ru-RU.

2. 

Чем интернационализация отличается от локализации и что делают сначала?

Сначала делают i18n: один раз, при разработке, программист делает код независимым от языка и региона — выносит тексты в ResourceBundle и форматирует даты через DateTimeFormatter с локалью. Это изменение кода.

Потом l10n повторяют для каждого нового языка или рынка: переводчик или разработчик добавляет файл переводов, например messages_de_DE.properties, не трогая код и без перекомпиляции.

Без i18n локализация превращается в переписывание программы: придётся искать и заменять строки по всему проекту.

3. 

Что зависит от локали, кроме языка интерфейса, и почему вывод форматтеров в Java 8 и Java 11+ может отличаться?

От локали зависят разделители в числах, порядок частей даты и названия месяцев, символ валюты и его место, первый день недели и порядок сортировки строк. Например, в Java 11+:

  • число 1234,5: 1,234.5 (en-US), 1.234,5 (de-DE), 1 234,5 с неразрывным пробелом (ru-RU);
  • дата 8 марта 2026 (LONG): March 8, 2026, 8. März 2026, 8 марта 2026 г.;
  • первый день недели: воскресенье в en-US, понедельник в de-DE и ru-RU.

С Java 9 данные о локалях по умолчанию берутся из Unicode CLDR (JEP 252), а не из старых таблиц JRE. Поэтому один и тот же форматтер может выдать другой символ валюты, другой пробел-разделитель или «г.» после года. Не сравнивайте в тестах отформатированные строки, записанные на другой версии JDK.

4. 

Как сделать Java-приложение интернационализированным?

  1. Вынести тексты. Вместо строки в коде — ключ, например message.welcome, в файлах messages.properties, messages_ru_RU.properties и т.д.
  2. Определить локаль — из настроек пользователя, заголовка HTTP-запроса или Locale.getDefault().
  3. Загрузить переводы через ResourceBundle.getBundle("messages", locale): он сам найдёт подходящий файл, а если файла для локали нет, возьмёт более общий.
  4. Форматировать с локалью: числа, валюты и даты выводить через NumberFormat, DateTimeFormatter, MessageFormat, а не склеивать строки вручную.
DateTimeFormatter formatter = DateTimeFormatter
        .ofLocalizedDate(FormatStyle.LONG)
        .withLocale(locale);
System.out.println(date.format(formatter));

Чтобы добавить язык, достаточно новой локали и файла переводов: названия месяцев и форматы берёт JDK.

5. 

Какую локаль использует Java, если её не указать, и когда нужен Locale.ROOT?

Многие методы без явной локали берут Locale.getDefault(). JVM определяет её при старте по настройкам операционной системы; переопределить можно параметрами -Duser.language=en -Duser.country=US или вызовом Locale.setDefault(...). С Java 7 она задаётся отдельно для отображения (Locale.Category.DISPLAY) и форматирования (Locale.Category.FORMAT).

Из-за этого один и тот же код по-разному работает на машине разработчика и на сервере. Внутренние данные (ключи, идентификаторы, форматы файлов) обрабатывают с Locale.ROOT, а локаль пользователя применяют только к тексту, который он увидит:

// с локалью ru-RU по умолчанию "%.2f" даёт "1234,50" - Double.parseDouble упадёт
String fixed = String.format(Locale.ROOT, "%.2f", 1234.5); // "1234.50"
String key = "title".toUpperCase(Locale.ROOT);             // "TITLE" даже в турецкой локали
6. 

Какие классы Java используются для интернационализации и что изменилось в современных версиях Java?

Сторонние библиотеки не нужны, всё есть в стандартной библиотеке:

  • Locale (java.util) — язык и регион, передаётся во все форматтеры;
  • ResourceBundle (java.util) — загружает переводы из .properties-файлов для нужной локали;
  • NumberFormat (java.text) — числа, валюты, проценты;
  • DateTimeFormatter (java.time.format) — даты и время;
  • MessageFormat (java.text) — шаблоны с параметрами вроде "Найдено {0} файлов";
  • Collator (java.text) — сортировка строк по алфавиту языка;
  • String.format(Locale, ...) — форматирование строк с явной локалью.

С Java 9 ResourceBundle читает properties-файлы в UTF-8 (JEP 226), и кириллицу больше не нужно экранировать утилитой native2ascii. Конструкторы new Locale("ru", "RU") устарели с Java 19 — вместо них Locale.of("ru", "RU") или Locale.forLanguageTag("ru-RU").

7. 

Что такое i18n и l10n и как расшифровываются эти сокращения?

i18n — сокращение слова internationalization (интернационализация): первая буква i, последняя n и 18 букв между ними. l10n так же сокращает localization (локализация): l, 10 букв, n. Такие сокращения называют нумеронимами.

  • Интернационализация — проектирование приложения так, чтобы для нового языка не нужно было перекомпилировать и пересобирать его: тексты хранятся в файлах свойств, а форматы чисел, дат и валют берутся из локали.
  • Локализация — адаптация приложения к конкретному языку и региону: перевод интерфейса и документации, настройка форматов дат, валют и чисел.
  • g11n (globalization) — i18n и l10n вместе; L10n с заглавной L пишут, чтобы букву не путали с цифрой 1.

В Java обе задачи связывает локаль — объект java.util.Locale, пара «язык + регион», например ru-RU.

8. 

Чем интернационализация отличается от локализации и что делают сначала?

Сначала делают i18n: один раз, при разработке, программист делает код независимым от языка и региона — выносит тексты в ResourceBundle и форматирует даты через DateTimeFormatter с локалью. Это изменение кода.

Потом l10n повторяют для каждого нового языка или рынка: переводчик или разработчик добавляет файл переводов, например messages_de_DE.properties, не трогая код и без перекомпиляции.

Без i18n локализация превращается в переписывание программы: придётся искать и заменять строки по всему проекту.

9. 

Что зависит от локали, кроме языка интерфейса, и почему вывод форматтеров в Java 8 и Java 11+ может отличаться?

От локали зависят разделители в числах, порядок частей даты и названия месяцев, символ валюты и его место, первый день недели и порядок сортировки строк. Например, в Java 11+:

  • число 1234,5: 1,234.5 (en-US), 1.234,5 (de-DE), 1 234,5 с неразрывным пробелом (ru-RU);
  • дата 8 марта 2026 (LONG): March 8, 2026, 8. März 2026, 8 марта 2026 г.;
  • первый день недели: воскресенье в en-US, понедельник в de-DE и ru-RU.

С Java 9 данные о локалях по умолчанию берутся из Unicode CLDR (JEP 252), а не из старых таблиц JRE. Поэтому один и тот же форматтер может выдать другой символ валюты, другой пробел-разделитель или «г.» после года. Не сравнивайте в тестах отформатированные строки, записанные на другой версии JDK.

10. 

Как сделать Java-приложение интернационализированным?

  1. Вынести тексты. Вместо строки в коде — ключ, например message.welcome, в файлах messages.properties, messages_ru_RU.properties и т.д.
  2. Определить локаль — из настроек пользователя, заголовка HTTP-запроса или Locale.getDefault().
  3. Загрузить переводы через ResourceBundle.getBundle("messages", locale): он сам найдёт подходящий файл, а если файла для локали нет, возьмёт более общий.
  4. Форматировать с локалью: числа, валюты и даты выводить через NumberFormat, DateTimeFormatter, MessageFormat, а не склеивать строки вручную.
DateTimeFormatter formatter = DateTimeFormatter
        .ofLocalizedDate(FormatStyle.LONG)
        .withLocale(locale);
System.out.println(date.format(formatter));

Чтобы добавить язык, достаточно новой локали и файла переводов: названия месяцев и форматы берёт JDK.

11. 

Какую локаль использует Java, если её не указать, и когда нужен Locale.ROOT?

Многие методы без явной локали берут Locale.getDefault(). JVM определяет её при старте по настройкам операционной системы; переопределить можно параметрами -Duser.language=en -Duser.country=US или вызовом Locale.setDefault(...). С Java 7 она задаётся отдельно для отображения (Locale.Category.DISPLAY) и форматирования (Locale.Category.FORMAT).

Из-за этого один и тот же код по-разному работает на машине разработчика и на сервере. Внутренние данные (ключи, идентификаторы, форматы файлов) обрабатывают с Locale.ROOT, а локаль пользователя применяют только к тексту, который он увидит:

// с локалью ru-RU по умолчанию "%.2f" даёт "1234,50" - Double.parseDouble упадёт
String fixed = String.format(Locale.ROOT, "%.2f", 1234.5); // "1234.50"
String key = "title".toUpperCase(Locale.ROOT);             // "TITLE" даже в турецкой локали
12. 

Какие классы Java используются для интернационализации и что изменилось в современных версиях Java?

Сторонние библиотеки не нужны, всё есть в стандартной библиотеке:

  • Locale (java.util) — язык и регион, передаётся во все форматтеры;
  • ResourceBundle (java.util) — загружает переводы из .properties-файлов для нужной локали;
  • NumberFormat (java.text) — числа, валюты, проценты;
  • DateTimeFormatter (java.time.format) — даты и время;
  • MessageFormat (java.text) — шаблоны с параметрами вроде "Найдено {0} файлов";
  • Collator (java.text) — сортировка строк по алфавиту языка;
  • String.format(Locale, ...) — форматирование строк с явной локалью.

С Java 9 ResourceBundle читает properties-файлы в UTF-8 (JEP 226), и кириллицу больше не нужно экранировать утилитой native2ascii. Конструкторы new Locale("ru", "RU") устарели с Java 19 — вместо них Locale.of("ru", "RU") или Locale.forLanguageTag("ru-RU").

Страница 1 из 1