Internationalization (i18n) in Java: Making Your Application Multilingual
Internationalization (often abbreviated as i18n — from the word internationalization, where 18 is the number of letters between the first 'i' and the last 'n') is the process of designing software so that it can be adapted to various languages and regional differences without modifying the source code. In Java, this task is solved elegantly and powerfully using built-in APIs: java.util.Locale, java.util.ResourceBundle, and a set of formatting classes.
In this article, we will break down how to implement support for multiple languages in a Java application using standard tools. You will learn how to create localization files, dynamically switch the language, and correctly format numbers, dates, and currencies.
Key Components of i18n in Java
Java provides three key elements for working with internationalization:
- Locale — an object representing a specific language and region (e.g., Russian in Russia —
ru_RU, English in the USA —en_US). - ResourceBundle — a class for loading localized resources (strings, messages, labels) from
.propertiesfiles or classes. - Formatters — classes from the
java.textpackage (NumberFormat,DateFormat,MessageFormat) for correctly displaying numbers, dates, and composite messages.
Step 1: Creating Resource Files
The traditional way to store localized strings is using .properties files. They are created according to the following rule:
Messages.properties # Default file (usually English)Messages_ru_RU.properties # For Russian (Russia)Messages_de_DE.properties # For German (Germany)Messages_fr.properties # For French (without region specification)Example content of the file Messages.properties (English, default):
welcome.message = Welcome to our application!farewell.message = Goodbye!date.format = dd/MM/yyyyExample content of the file Messages_ru_RU.properties (Russian):
welcome.message = Добро пожаловать в наше приложение!farewell.message = До свидания!date.format = dd.MM.yyyyImportant: the files must be in ISO 8859-1 (Latin-1) encoding or use Unicode escaping for characters not included in this encoding. For Russian letters, escaping will be required, for example \\u0414\\u043E\\u0431\\u0440\\u043E. However, in modern development environments (IntelliJ IDEA, Eclipse) and when building with Maven/Gradle, this is often automated.
Step 2: Loading Resources in Code
To use localized strings, simply create a Locale object and get the corresponding ResourceBundle:
import java.util.Locale;import java.util.ResourceBundle;
public class I18nDemo { public static void main(String[] args) { // Create a locale for the Russian language Locale ruLocale = new Locale("ru", "RU"); // Load the bundle (base file name is "Messages") ResourceBundle bundle = ResourceBundle.getBundle("Messages", ruLocale);
// Get the strings String welcome = bundle.getString("welcome.message"); String farewell = bundle.getString("farewell.message");
System.out.println(welcome); // Добро пожаловать в наше приложение! System.out.println(farewell); // До свидания! }}If the file for a specific locale is not found, Java automatically uses the default file (Messages.properties).
Step 3: Dynamic Language Switching
In a web appli