Appearance
Lesson 01 · Locale & Resource Bundles
Objectives
After this lesson you will be able to:
- Create and read a
Locale. - Load a
ResourceBundle(property or class based). - Explain the lookup and fallback algorithm.
Locale
A Locale identifies a language + region (and optionally script/variant). Build one with the builder, the constants, or forLanguageTag.
java
Locale fr = Locale.FRANCE; // language fr, country FR
Locale us = Locale.US; // en_US
Locale custom = new Locale.Builder()
.setLanguage("en").setRegion("GB").build();
Locale tag = Locale.forLanguageTag("pt-BR");
fr.getLanguage(); // "fr"
fr.getCountry(); // "FR"Gotcha
The language code is lowercase, the country code UPPERCASE (en_US, fr_CA). The legacy constructor new Locale("en", "US") still works but the Locale.Builder / forLanguageTag are preferred.
ResourceBundle
A ResourceBundle maps keys to locale-specific values. The common kind is a property bundle: a set of .properties files sharing a base name.
messages.properties # default (fallback)
messages_fr.properties # French
messages_fr_CA.properties # French (Canada)properties
# messages_fr.properties
greeting=Bonjourjava
ResourceBundle rb = ResourceBundle.getBundle("messages", Locale.FRANCE);
String hello = rb.getString("greeting"); // "Bonjour"A class bundle instead subclasses ListResourceBundle and returns an Object[][] of key/value pairs — useful for non-string values.
Lookup and fallback
For getBundle("messages", fr_CA), Java searches most-specific to least, and falls back to the default locale's bundles, then the base bundle:
messages_fr_CA → messages_fr → messages_<defaultLocale...> → messages (base)The first bundle that contains the key wins; a missing key throws MissingResourceException. Within a found bundle, keys also fall back up the chain.
Exam trap
Bundle selection picks the most specific file available, but key lookup then walks up the parent chain — so messages_fr_CA automatically inherits keys from messages_fr and the base messages. A key missing from all levels throws MissingResourceException (unchecked).
SDET note
A ListResourceBundle subclass needs no external files, which makes it ideal for deterministic tests of localization logic — you control the data in code instead of depending on classpath resources.
Key Takeaways
- A
Localeis language (lowercase) + country (UPPERCASE); preferLocale.Builder/forLanguageTagover the legacy constructor. ResourceBundle.getBundle(base, locale)loads.properties(property bundle) or aListResourceBundlesubclass (class bundle).- Selection is most-specific-first with fallback to the default locale then the base; key lookup walks up the parent chain.
- A key absent from every level throws
MissingResourceException.
Lesson Quiz
What is the correct case for the locale en_US?
For getBundle("m", fr_CA), which is searched FIRST?
A key exists only in messages.properties (base). You load messages_fr. Does getString find it?
A key missing from every bundle level throws...
Next: Formatting & Parsing. Run the matching code in labs/src/main/java/com/jse21/m09_localization/.