Every international-oriented language needs to have its own internationalization solution, and Java from the beginning handles all strings in Unicode, which gives Java an important feature of internationalization. In addition to providing Unicode, Java also needs to address the representations of different locales.

Locale

The Java.util package provides the Locale class to handle internationalization issues on different languages and regions. The Locale class allows you to customize information about a Locale, and the Locale class provides the following constructor to construct a Locale object.

public final class Locale implements Cloneable.Serializable {
    Construct the locale from language, country, and variant
    public Locale(String language, String country, String variant) {...}// Construct the locale from language and country
    public Locale(String language, String country) {...}Construct the locale from the language code
    public Locale(String language) {...}}Copy the code

A Locale allows you to set a language, country, or region, and variants. Languages are represented by two or three lowercase letters, such as en, en, or de. You can see the ISO-639-1 language code identifier here.

Locale contains a number of predefined Locale languages, which specify only the language but not the country, as shown below.

/ / English
public static final Locale ENGLISH = createConstant("en"."");
/ / French
public static final Locale FRENCH = createConstant("fr"."");
/ / German
public static final Locale GERMAN = createConstant("de"."");
// Italian
public static final Locale ITALIAN = createConstant("it"."");
/ / Japanese
public static final Locale JAPANESE = createConstant("ja"."");
/ / Korean
public static final Locale KOREAN = createConstant("ko"."");
/ / Chinese
public static final Locale CHINESE = createConstant("zh"."");
// Simplified Chinese
public static final Locale SIMPLIFIED_CHINESE = createConstant("zh"."CN");
// Traditional Chinese
public static final Locale TRADITIONAL_CHINESE = createConstant("zh"."TW");
Copy the code

Countries and regions are also represented by two letters or three numbers, such as CN, US, or DE. You can view the country or region identifier in ISO-3166-1.

Locale objects are predefined for each country, as shown in the following figure.

/ / French
public static final Locale FRANCE = createConstant("fr"."FR");
/ / Germany
public static final Locale GERMANY = createConstant("de"."DE");
/ / Italy
public static final Locale ITALY = createConstant("it"."IT");
/ / Japan
public static final Locale JAPAN = createConstant("ja"."JP");
/ / South Korea
public static final Locale KOREA = createConstant("ko"."KR");
/ / China
    public static final Locale CHINA = SIMPLIFIED_CHINESE;
// People's Republic of China
public static final Locale PRC = SIMPLIFIED_CHINESE;
/ / Taiwan
public static final Locale TAIWAN = TRADITIONAL_CHINESE;
/ / the UK
public static final Locale UK = createConstant("en"."GB");
/ / the U.S.
public static final Locale US = createConstant("en"."US");
/ / Canada
public static final Locale CANADA = createConstant("en"."CA");
// French Canadian
public static final Locale CANADA_FRENCH = createConstant("fr"."CA");
// Represents the constant of the root locale
public static final Locale ROOT = createConstant(""."");
Copy the code

Variant used to specify various miscellaneous features, and if there are multiple variable values, each indicating its own semantics, the values should be sorted by importance and separated by underscores. The variant field is case sensitive.

Java SE 7 also provides the forLanguageTag static method to build Locale objects, as shown below:

Locale zhChinese = Locale.forLanguageTag("zh-CN");
Locale twChinese = Locale.forLanguageTag("zh-TW");
System.out.println(zhChinese.getDisplayName());
System.out.println(twChinese.getDisplayName());
// Chinese (Chinese)
// Chinese (Taiwan)
Copy the code

The setDefault method in Locale can change the default Locale and use getDefault to get the current Locale object, as shown below:

System.out.println(Locale.getDefault());
Locale.setDefault(Locale.US);
System.out.println(Locale.getDefault());
// zh_CN
// en-US
Copy the code

The getAvailableLocale static method provided in Locale returns an array of all locales that the JVM can recognize.

ResourceBundle

After setting the specific language and Locale using Locale, you can use ResourceBundle to load resources for different locales. Resources need to be stored in the Resources resource bundle, and resource files need to be set for different locales. As shown below, resource files are automatically bound based on locale using the getBundle static method provided by the ResourceBundle class.

Locale locale = Locale.CHINA;
ResourceBundle bundle = ResourceBundle.getBundle("i18n", locale);
Copy the code

To find a specific string, call

String language = bundle.getString("language");
Copy the code

Here the resource file names use a common naming convention, and then, depending on the locale, identifies additional parts of its local information. For example, if the name of a resource package is I18N, the following figure shows the resources corresponding to the Chinese and English environments.

You can put the default resource in a file without the suffix i18n, and then when the getBundle method locates i18n_zh_CN, it will continue to look for files i18n_zh and the default file i18n. If these files exist, They become the parent of i18n_zh_CN in the resource hierarchy. Later, when looking for a resource, if it is not found in the current resource file, the parent resource file is looked up.

In a file with the suffix.properties, the properties are in the form of = separated key-value pairs, as follows:

language=Chinese
color=red
Copy the code

ResourceBundle is an abstract class, as shown below.

public abstract class ResourceBundle {... }Copy the code

Classes that inherit ResourceBundle have a concrete implementation class PropertyResourceBundle and an abstract class ListResourceBundle. PropertyResourceBundle is a concrete subclass that enables A ResourceBundle to read properties resource files without directly using PropertyResourceBundle. Resourcebundle. getBundle automatically looks up the corresponding properties file and creates a PropertyResourceBundle that references it. However, the values provided by the Properties resource file can only be strings.

If you want to provide additional resources, you need to inherit the ListResourceBundle abstract class and put all resources into an array of objects and provide lookup, as shown below.

public class I18N extends ListResourceBundle {
    @Override
    protected Object[][] getContents() {
        return new Object[][]{
                {"color"."yellow"}}; }}public class I18N_zh extends ListResourceBundle {
    @Override
    protected Object[][] getContents() {
        return new Object[][]{
                {"language".new String[]{"Simplified Chinese"."Traditional Chinese"}}}; }}public class I18N_zh_CN extends ListResourceBundle {
    @Override
    protected Object[][] getContents() {
        return new Object[][]{
                {"language"."Simplified Chinese"},
                {"color".new String[]{"Red"."Yellow"."Black"}}}; }}Copy the code

The classes here are also named using standard naming conventions. Then use the getBundle method to load the corresponding class:

ResourceBundle bundle = ResourceBundle.getBundle("I18N", Locale.forLanguageTag("zh-CN"));
System.out.println(bundle.getString("language"));
System.out.println(Arrays.toString(bundle.getStringArray("color")));
Copy the code

The ResourceBundle class can also extend it by inheriting the ResourceBundle class, but with two methods: enumerating all keys and finding the corresponding value with the given key:

Enumeration<String> getKeys(a);
Object handleGetObject(String key);
Copy the code

The getObject method of the ResourceBundle class calls the handleGetObject method you provided.

NumberFormat

NumberFormat in the java.text package can format and parse numeric values for different locales.

Use the getNumberInstance static method to get an instance of a number that is formatted and parsed, and then format the corresponding number to see how the corresponding Locale instance is formatted differently.

NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.SIMPLIFIED_CHINESE);
String result = numberFormat.format(2021.0731);
System.out.println(result);
Copy the code

The result was 2,021.073, compared with 2,021.073 for the United States and 2.021,073 for Germany. When the numeric value is currency, use the getCurrencyInstance static method, as shown below.

NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
String result = currencyFormat.format(2021.0731);
System.out.println(result);
Copy the code

The result is ¥2,021.07, and the result is $2,021.07 and 2.021,07 €, respectively, for America and Germany.

When dealing with Currency, you can use the Currency class to control the Currency. You can pass in a Currency identifier and return the Currency object through the static method currence. getInstance, and then call the setCurrency method in NumberFormat. The following example is to set the format of RMB for the German user, as shown below.

NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
currencyFormat.setCurrency(Currency.getInstance("CNY"));
String result = currencyFormat.format(2021.0731);
System.out.println(result);    / / 2.021, 07 CN selections
Copy the code

Currency identifiers are defined by ISO-4217. Here are a few of them.

Monetary value identifier Monetary value identifier
U.S.Dollar USD Chinese Renminbi(Yuan) CNY
Euro EUR Indian Rupee INR
British Pound GBP Russian Ruble RUB
Japanese Yen JPY

DateTimeFormatter

Every country and region for the date and time display can’t be the same, provides Java. Java SE 8 time. DateTimeFormatter class to handle the date and time, associated with the Locale format and precipitation in line with the representation of the local date and time. Set different locales using withLocale in DateTimeFormatter, as shown below.

DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.SIMPLIFIED_CHINESE);
Copy the code

After that, you can format LocaleDate, LocaleDateTime, LocaleTime, and ZonedDateTime.

ZonedDateTime appointment = ZonedDateTime.now();
String formatted = formatter.format(appointment);
Copy the code

The output result is Saturday, July 31, 2021, and the result is Saturday, July 31, 2021 and Samstag, 31. Juli 2021, respectively. When exporting the first day of a Locale, you can use the Locale Settings, as shown below.

DayOfWeek first = WeekFields.of(locale).getFirstDayOfWeek();
Copy the code

MessageFormat

Java provides java.text.MessageFormat to format messages. The following paragraph:

String msg = "On {2}, {0} destroyed {1} houses and caused {3} of damage."
Copy the code

The numbers in parentheses are placeholders that can be replaced with the actual value by the messageFormat. format static method. It is a varargs method, so arguments can be provided as follows:

String result = MessageFormat.format(msg, "a hurricane".99.new GregorianCalendar(1999.0.1).getTime(), 10.0 e8);
Copy the code

The output is:

On 1/1/99 12:00 AM, a hurricane destroyed 99 houses and caused 100,000,000 of damage.
Copy the code

The above example can also provide alternative formats for placeholders, making the print more elaborate.

On {2, date, long}, {0} destroyed {1} houses and caused {3, number, currency} of damage.
Copy the code

The output is:

On January 1, 1999, a hurricane destroyed 99 houses and caused $100,000,000 of damage.
Copy the code

Generally, a placeholder index can be followed by a type and a style, separated by commas.

Messageformat. format The static method formats the value using the current Locale. To format with any Locale, you need to provide the class with a varargs method that you can use. You need to place the values to be formatted in an Object[] array, as shown below.

MessageFormat mf = new MessageFormat(pattern, locale);
String msg = mf.format(new Object[] {values});
Copy the code

We are looking forward to your attention on the public account “Hai Ren Ji”.

Reply “Resources” to get free learning resources!