Java Locale Class: What a Locale Is and How to Create One - Quiz
Total: 12 questions
1. What is a locale, and what is the java.util.Locale class responsible for?
What is a locale, and what is the java.util.Locale class responsible for?
A locale is a set of regional settings: a language, a country (region) and, when needed, a script and a variant. In Java it is represented by the java.util.Locale class, for example en_US for English, United States.
A Locale does not format anything by itself. It is a label for a language and region that you pass to NumberFormat, DateTimeFormatter, ResourceBundle, String.format and other classes, and they pick the number separators, month names or translation file.
When the JVM starts, it takes the default locale from the operating system settings, but you can change it or pass a specific locale to a particular method.
2. What are the ways to create a Locale object, and which one should you use in modern Java?
What are the ways to create a Locale object, and which one should you use in modern Java?
- A constant:
Locale.FRANCE,Locale.US. You can't get it wrong, but there are few constants. Locale.of("de", "DE")(Java 19+): the main way; it does not validate its arguments.Locale.forLanguageTag("de-DE")(Java 7+): from a BCP 47 tag with a hyphen; an ill-formed subtag is silently dropped.new Locale.Builder().setLanguage("de").setRegion("DE").build()(Java 7+): validates the values and throwsIllformedLocaleException.new Locale("de", "DE"): the constructor, deprecated since Java 19.
The three modern ways produce equal objects: Locale.of("de", "DE").equals(Locale.forLanguageTag("de-DE")) returns true. The language code is lowercase (ISO 639), the country code is uppercase (ISO 3166). On Java 8–18, where Locale.of does not exist, use Locale.forLanguageTag.
3. Which constants does the Locale class have, and why is there no constant for most countries?
Which constants does the Locale class have, and why is there no constant for most countries?
There are two kinds of constants:
- language + country:
Locale.US(en_US),Locale.UK(en_GB),Locale.CANADA,Locale.CANADA_FRENCH,Locale.FRANCE,Locale.GERMANY,Locale.ITALY,Locale.JAPAN,Locale.KOREA,Locale.CHINA,Locale.TAIWAN; - language only:
Locale.ENGLISH(en),Locale.FRENCH,Locale.GERMANand others; - plus the neutral
Locale.ROOT(added in Java 6).
The country and language constants were added in Java 1.1 for a small set of locales, and no new country constants have been added since. So for Brazil, Spain and most other countries you create the locale with Locale.of("pt", "BR") or declare your own constant: static final Locale BRAZIL = Locale.of("pt", "BR");.
Two common traps: Locale.UK is the United Kingdom, not Ukraine (a Ukrainian locale is Locale.of("uk", "UA")), and Locale.ENGLISH has no country and therefore no currency, unlike Locale.US.
4. What is Locale.ROOT, and why is it better than Locale.US for machine-readable formats?
What is Locale.ROOT, and why is it better than Locale.US for machine-readable formats?
Locale.ROOT is the neutral locale whose language and country are both the empty string. Its toString() returns "" and toLanguageTag() returns "und" (the BCP 47 tag for an "undetermined" language). Locale.ROOT equals Locale.of("") and is the base of all other locales.
Where it is used:
- operations that must not depend on language:
toUpperCase(Locale.ROOT),String.format(Locale.ROOT, ...)for keys, logs, CSV and protocols; - base resources: a
text.propertiesfile without a suffix corresponds toLocale.ROOT.
Locale.US also uses a dot as the decimal separator, but it holds the settings of real American English users. Locale.ROOT is designed for language-independent operations and tells the reader of the code right away that the result is not meant for humans.
5. How do you get and change the default locale in Java, and why shouldn't you call Locale.setDefault on a server?
How do you get and change the default locale in Java, and why shouldn't you call Locale.setDefault on a server?
Locale.getDefault() returns the current locale. The JVM determines it once, at startup, from the operating system settings. You can change it with Locale.setDefault(Locale.CANADA) or with startup options:
java -Duser.language=de -Duser.country=DE Main
Since Java 7 the default locale has two Locale.Category values: DISPLAY controls the language of names (getDisplayCountry() and so on), FORMAT controls the format of numbers, dates and currencies. setDefault(Locale) changes both, while setDefault(Category, Locale) changes only one and does not touch the general getDefault(). setDefault(null) throws a NullPointerException.
setDefault affects the whole JVM, not a thread or a user. On a server that handles users with different languages at the same time, pass the request locale to formatters explicitly: NumberFormat.getInstance(locale), ResourceBundle.getBundle("text", locale) (in Spring it is kept by LocaleContextHolder).
6. How do you get a Locale from a string like "en_US", and which mistakes go unnoticed?
How do you get a Locale from a string like "en_US", and which mistakes go unnoticed?
toString() gives a code with an underscore (en_US), but forLanguageTag expects a BCP 47 tag with a hyphen (en-US). So replace the underscore first:
Locale good = Locale.forLanguageTag("en_US".replace('_', '-')); // en_US
String tag = good.toLanguageTag(); // "en-US"
What happens without the replacement:
Locale.forLanguageTag("en_US")returns an empty locale equal toLocale.ROOTwithout any exception, andResourceBundlequietly loads the base resource file;Locale.of("en_US")does not validate its argument: the language becomes"en_us"and the country is empty;new Locale.Builder().setLanguage("en_US")throws anIllformedLocaleException.
If a locale code comes from outside (settings, a database, an HTTP request), use Locale.Builder: the error shows up immediately instead of as an untranslated text.
7. What is a locale, and what is the java.util.Locale class responsible for?
What is a locale, and what is the java.util.Locale class responsible for?
A locale is a set of regional settings: a language, a country (region) and, when needed, a script and a variant. In Java it is represented by the java.util.Locale class, for example en_US for English, United States.
A Locale does not format anything by itself. It is a label for a language and region that you pass to NumberFormat, DateTimeFormatter, ResourceBundle, String.format and other classes, and they pick the number separators, month names or translation file.
When the JVM starts, it takes the default locale from the operating system settings, but you can change it or pass a specific locale to a particular method.
8. What are the ways to create a Locale object, and which one should you use in modern Java?
What are the ways to create a Locale object, and which one should you use in modern Java?
- A constant:
Locale.FRANCE,Locale.US. You can't get it wrong, but there are few constants. Locale.of("de", "DE")(Java 19+): the main way; it does not validate its arguments.Locale.forLanguageTag("de-DE")(Java 7+): from a BCP 47 tag with a hyphen; an ill-formed subtag is silently dropped.new Locale.Builder().setLanguage("de").setRegion("DE").build()(Java 7+): validates the values and throwsIllformedLocaleException.new Locale("de", "DE"): the constructor, deprecated since Java 19.
The three modern ways produce equal objects: Locale.of("de", "DE").equals(Locale.forLanguageTag("de-DE")) returns true. The language code is lowercase (ISO 639), the country code is uppercase (ISO 3166). On Java 8–18, where Locale.of does not exist, use Locale.forLanguageTag.
9. Which constants does the Locale class have, and why is there no constant for most countries?
Which constants does the Locale class have, and why is there no constant for most countries?
There are two kinds of constants:
- language + country:
Locale.US(en_US),Locale.UK(en_GB),Locale.CANADA,Locale.CANADA_FRENCH,Locale.FRANCE,Locale.GERMANY,Locale.ITALY,Locale.JAPAN,Locale.KOREA,Locale.CHINA,Locale.TAIWAN; - language only:
Locale.ENGLISH(en),Locale.FRENCH,Locale.GERMANand others; - plus the neutral
Locale.ROOT(added in Java 6).
The country and language constants were added in Java 1.1 for a small set of locales, and no new country constants have been added since. So for Brazil, Spain and most other countries you create the locale with Locale.of("pt", "BR") or declare your own constant: static final Locale BRAZIL = Locale.of("pt", "BR");.
Two common traps: Locale.UK is the United Kingdom, not Ukraine (a Ukrainian locale is Locale.of("uk", "UA")), and Locale.ENGLISH has no country and therefore no currency, unlike Locale.US.
10. What is Locale.ROOT, and why is it better than Locale.US for machine-readable formats?
What is Locale.ROOT, and why is it better than Locale.US for machine-readable formats?
Locale.ROOT is the neutral locale whose language and country are both the empty string. Its toString() returns "" and toLanguageTag() returns "und" (the BCP 47 tag for an "undetermined" language). Locale.ROOT equals Locale.of("") and is the base of all other locales.
Where it is used:
- operations that must not depend on language:
toUpperCase(Locale.ROOT),String.format(Locale.ROOT, ...)for keys, logs, CSV and protocols; - base resources: a
text.propertiesfile without a suffix corresponds toLocale.ROOT.
Locale.US also uses a dot as the decimal separator, but it holds the settings of real American English users. Locale.ROOT is designed for language-independent operations and tells the reader of the code right away that the result is not meant for humans.
11. How do you get and change the default locale in Java, and why shouldn't you call Locale.setDefault on a server?
How do you get and change the default locale in Java, and why shouldn't you call Locale.setDefault on a server?
Locale.getDefault() returns the current locale. The JVM determines it once, at startup, from the operating system settings. You can change it with Locale.setDefault(Locale.CANADA) or with startup options:
java -Duser.language=de -Duser.country=DE Main
Since Java 7 the default locale has two Locale.Category values: DISPLAY controls the language of names (getDisplayCountry() and so on), FORMAT controls the format of numbers, dates and currencies. setDefault(Locale) changes both, while setDefault(Category, Locale) changes only one and does not touch the general getDefault(). setDefault(null) throws a NullPointerException.
setDefault affects the whole JVM, not a thread or a user. On a server that handles users with different languages at the same time, pass the request locale to formatters explicitly: NumberFormat.getInstance(locale), ResourceBundle.getBundle("text", locale) (in Spring it is kept by LocaleContextHolder).
12. How do you get a Locale from a string like "en_US", and which mistakes go unnoticed?
How do you get a Locale from a string like "en_US", and which mistakes go unnoticed?
toString() gives a code with an underscore (en_US), but forLanguageTag expects a BCP 47 tag with a hyphen (en-US). So replace the underscore first:
Locale good = Locale.forLanguageTag("en_US".replace('_', '-')); // en_US
String tag = good.toLanguageTag(); // "en-US"
What happens without the replacement:
Locale.forLanguageTag("en_US")returns an empty locale equal toLocale.ROOTwithout any exception, andResourceBundlequietly loads the base resource file;Locale.of("en_US")does not validate its argument: the language becomes"en_us"and the country is empty;new Locale.Builder().setLanguage("en_US")throws anIllformedLocaleException.
If a locale code comes from outside (settings, a database, an HTTP request), use Locale.Builder: the error shows up immediately instead of as an untranslated text.