Localization and Formatting
The exam checks bundle lookup order, locale-sensitive formatting, and which formatter classes are thread-safe.
Locales and resource bundles
Locale combines language and country, e.g. Locale.forLanguageTag("fr-CA"), and Locale.getDefault() can be split by Locale.Category.DISPLAY and FORMAT. ResourceBundle.getBundle("Messages", locale) searches Messages_fr_CA, then Messages_fr, then the base bundle Messages, and finally falls back to the default locale before throwing MissingResourceException. .properties bundles are read as UTF-8 since Java 9; older code needs \uXXXX escapes. Keys are case-sensitive.
Numbers, currency and dates
NumberFormat.getInstance(locale), getCurrencyInstance, getPercentInstance and getIntegerInstance handle grouping and decimal separators; setMaximumFractionDigits and setParseIntegerOnly tune them. NumberFormat and DateFormat are not thread-safe, so create per use. DateTimeFormatter is immutable and thread-safe; use ofPattern("dd MMM yyyy", locale) or ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale).
Messages
MessageFormat.format("Hello {0}, you owe {1,number,currency}", name, amount) supports number, date and choice subformats. Beware that MessageFormat treats a single quote as a quoting character.
Worked example
With bundles Messages.properties, Messages_fr.properties and Messages_fr_CA.properties present, requesting fr-CA resolves to Messages_fr_CA; with only Messages_fr and Messages present, it resolves to Messages_fr. Reasoning: the search walks from the most specific locale upward, then the default locale, then the base bundle.
Traps
Relying on the JVM default locale in server code; sharing a NumberFormat across threads; forgetting MissingResourceException is unchecked; assuming date patterns are locale-independent.