Интернационализация (i18n) в Java: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Интернационализация (i18n) в Java: Полное руководство

Интернационализация (сокращённо i18n — от слова internationalization, где между первой буквой 'i' и последней 'n' стоит 18 букв) — это процесс проектирования программного обеспечения таким образом, чтобы оно могло быть адаптировано для различных языков и регионов без внесения изменений в исходный код. Java предоставляет мощный и встроенный набор инструментов для интернационализации, который позволяет разработчикам легко создавать многоязычные приложения.

В этой статье мы подробно разберём основные компоненты i18n в Java: Locale, ResourceBundle, файлы свойств и MessageFormat. Вы научитесь правильно структурировать локализованные ресурсы и обрабатывать исключения, связанные с отсутствием перевода.

1. Основные компоненты i18n в Java

Интернационализация в Java базируется на трёх ключевых элементах:

  • Locale — объект, представляющий конкретную географическую, политическую или культурную область. Он содержит информацию о языке, стране (опционально) и варианте (опционально).
  • ResourceBundle — класс, который загружает локализованные ресурсы (строки, форматы) из файлов свойств (.properties) или других источников.
  • Файлы свойств — текстовые файлы с расширением .properties, где хранятся пары ключ=значение. Имя файла строится по правилам: ИмяБазовое_язык_СТРАНА.properties.

Пример структуры файлов для русского и английского языков:

Messages.properties          // Файл по умолчанию
Messages_en.properties       // Английский (общий)
Messages_en_US.properties    // Английский (США)
Messages_ru_RU.properties    // Русский (Россия)

2. Создание файлов свойств

Создадим базовый файл Messages.properties (значения по умолчанию — на английском):

greeting=Hello
farewell=Goodbye
app.name=My Application

Теперь создадим русскую локализацию Messages_ru_RU.properties:

greeting=Здравствуйте
farewell=До свидания
app.name=Моё приложение

Для английского (США) — Messages_en_US.properties:

greeting=Hello
farewell=Goodbye
app.name=My Application

3. Использование Locale и ResourceBundle

Для загрузки локализованных строк используется следующий код:

import java.util.Locale;
import java.util.ResourceBundle;

public class I18nExample {
    public static void main(String[] args) {
        // Устанавливаем локаль (например, русский язык, Россия)
        Locale ruLocale = new Locale("ru", "RU");
        ResourceBundle bundle = ResourceBundle.getBundle("Messages", ruLocale);
        
        // Получаем локализованные строки
        String greeting = bundle.getString("greeting");
        String farewell = bundle.getString("farewell");
        String appName = bundle.getString("app.name");
        
        System.out.println(greeting + " " + farewell); // Здравствуйте До свидания
        System.out.println(appName);                   // Моё приложение
    }
}

Если локаль не найдена, Java автоматически использует цепочку поиска:

  1. Сначала ищет файл с точным совпадением (Messages_ru_RU.properties).
  2. Затем — без страны (Messages_ru.properties).
  3. Далее — базовый файл (Messages.properties).
  4. Если ничего не найдено — выбрасывается исключение MissingResourceException.

4. Форматирование сообщений с MessageFormat

Часто строки содержат переменные части. Для этого используется MessageFormat. Пример с динамическими данными:

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

public class MessageFormatExample {
    public static void main(String[] args) {
        Locale ruLocale = new Locale("ru", "RU");
        ResourceBundle bundle = ResourceBundle.getBundle("Messages", ruLocale);
        
        // В файле Messages_ru_RU.properties добавим:
        // welcome.message=Добро пожаловать, {0}! У вас {1} новых сообщений.
        String pattern = bundle.getString("welcome.message");
        
        String formatted = MessageFormat.format(pattern, "Алексей", 5);
        System.out.println(formatted); 
        // Вывод: Добро пожаловать, Алексей! У вас 5 новых сообщений.
    }
}

Шаблон {0} и {1} заменяются переданными аргументами. MessageFormat

Рекомендаций