Localization practice questions

From OCP Java SE 17 (1Z0-829) · 16 questions on this topic

Localization practice questions from OCP Java SE 17 (1Z0-829). This pack has 16 questions tagged Localization, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Localization

  1. Question 1

    What does this print? ```java import java.io.*; import java.util.*; public class Main { static class Child extends PropertyResourceBundle { Child(Reader reader, ResourceBundle parent) throws IOException { super(reader); setParent(parent); } } public static void main(String[] args) throws IOException { ResourceBundle base = new PropertyResourceBundle( new StringReader("greeting=Hello\nfarewell=Bye\n")); ResourceBundle fr = new Child(new StringReader("greeting=Bonjour\n"), base); System.out.println(fr.getString("greeting") + " " + fr.getString("farewell") + " " + fr.containsKey("farewell") + " " + fr.keySet().size()); } } ```

    1. A. Bonjour Bye false 2

      Assumes containsKey is a local check while getString searches the parent chain; both consult this bundle and its parents, so containsKey("farewell") is true, not false.

    2. B. Bonjour Bye true 1

      Gets the lookups right but assumes keySet() reports only the child's own keys; keySet() is specified over this bundle and its parents, so the union has size 2, not 1.

    3. C. Bonjour Bye true 2Correct answer

      The child overrides greeting (Bonjour) while farewell falls through to the parent (Bye); containsKey and keySet both walk the parent chain, so containsKey is true and the key union size is 2.

    4. D. A MissingResourceException is thrown for the key farewell

      Assumes a bundle can only serve keys it declares itself; MissingResourceException is thrown only when a key is absent from the child and every parent, and farewell exists in the parent.

    Explanation

    Trace: this is the parent chain that `ResourceBundle.getBundle` normally builds for you, assembled by hand so you can see the mechanism. The child bundle defines only `greeting`; its parent defines `greeting` and `farewell`. - `getString("greeting")` finds `Bonjour` in the child and stops — the child wins over the parent, which is why a country bundle can override just a few keys. - `getString("farewell")` misses in the child, so `getObject` walks to the parent and returns `Bye`. This is the fallback that makes partial translations work. - `containsKey` is documented to consult *this bundle and its parents*, so it is `true`. - `keySet()` is likewise documented to return the keys of *this bundle and its parents* — the union `{greeting, farewell}` — so the size is 2. Why the others are wrong: `Bonjour Bye true 1` gets the lookups right but assumes `keySet()` reports only the keys physically in the child. That describes the protected `handleKeySet()`, not the public `keySet()`; the child on its own really does hold one key, which is exactly why this distractor is tempting. `Bonjour Bye false 2` assumes `containsKey` is a local check while `getString` searches the chain. That would be an incoherent API — both walk the same parent chain. `A MissingResourceException is thrown for the key farewell` assumes a bundle can only serve keys it declares itself. `MissingResourceException` is thrown only when the key is absent from the child *and* from every parent. Exam tip: for `ResourceBundle`, "most specific wins, missing keys fall through to the parent" governs `getObject`, `getString`, `containsKey`, `getKeys` and `keySet` alike. The trap in the other direction: the parent chain is built from the *base name*, so it never fills a gap from an unrelated bundle — only from `Msg_fr` up to `Msg`.

  2. Question 2

    When looking up a key, in what order does ResourceBundle.getBundle search candidate bundles?

    1. A. Most specific (language_country_variant) first, falling back toward the base bundleCorrect answer

      getBundle builds candidate names from the requested locale (language_country_variant, then language_country, then language) and falls back through the default locale's candidates to the base bundle, so lookup always proceeds most-specific-first (Javadoc 17 ResourceBundle.getBundle candidate order).

    2. B. Alphabetical order of property files

      Assumes the search order comes from file-name sorting; in fact the order is derived from the locale, never from alphabetical property-file names.

    3. C. Only the exact locale match; no fallback occurs

      Denies the fallback that is the defining feature of the mechanism; exact-match-only lookup would make MissingResourceException the common case.

    4. D. Base bundle first, then more specific ones

      Reverses the direction: the base bundle is the last resort, consulted only after both the requested and default locales fail, not the first candidate tried.

    Explanation

    ResourceBundle.getBundle derives its search order from the requested locale, building candidate names from most specific to least: language_country_variant, then language_country, then language. It walks that chain most-specific-first, and if the requested locale yields nothing it retries the same sequence against the JVM's default locale before finally consulting the base bundle. Once a bundle loads, its parent chain serves individual keys, so the base bundle is a last resort rather than a starting point.

  3. Question 3

    What does this print? ```java import java.text.*; import java.util.*; public class Main { public static void main(String[] args) { NumberFormat nf = NumberFormat.getInstance(Locale.US); nf.setMaximumFractionDigits(2); System.out.println(nf.format(1234.5678)); } } ```

    1. A. 1,234.57Correct answer

      The US instance groups with commas and, with setMaximumFractionDigits(2), rounds the fraction to two digits; .5678 rounds up to .57, giving 1,234.57.

    2. B. 1,234.56

      Assumes truncation, but NumberFormat rounds, and the discarded digits push the second fraction digit up rather than leaving .56.

    3. C. 1234.57

      Drops the grouping separator, but grouping stays on by default for getInstance; disabling it would require setGroupingUsed(false).

    4. D. 1,234.568

      Keeps three fraction digits, which is only the default cap; the explicit setMaximumFractionDigits(2) overrides it to two.

    Explanation

    NumberFormat.getInstance for the US groups thousands with commas and by default caps the fraction at three digits, but setMaximumFractionDigits(2) lowers that cap to two. Formatting 1234.5678 rounds at the second fraction digit rather than truncating, so .5678 becomes .57. Because grouping remains enabled, the result carries a thousands comma.

  4. Question 4

    What does NumberFormat.getCurrencyInstance(Locale.US).format(1234.5) produce? ```java import java.text.*; import java.util.*; public class Main { public static void main(String[] args) { System.out.println(NumberFormat.getCurrencyInstance(Locale.US).format(1234.5)); } } ```

    1. A. 1234.5

      The raw double; a currency format never emits the bare number without a symbol, grouping, or the currency's fraction digits.

    2. B. $1234.5

      Applies the symbol but skips both the grouping separator and the two-digit fraction padding that the currency format enforces.

    3. C. USD 1234.50

      Uses the ISO 4217 currency code; getCurrencyInstance(Locale.US) emits the symbol, not the code, even though it does show two fraction digits.

    4. D. $1,234.50Correct answer

      The US currency instance applies the currency symbol, comma grouping, and exactly two fraction digits (the dollar's default), padding 1234.5 to 1,234.50 (Javadoc 17 NumberFormat.getCurrencyInstance).

    Explanation

    A currency NumberFormat pulls its symbol, grouping separator, and decimal character from the locale and formats to the currency's default fraction digits, which for the US dollar is two. Formatting 1234.5 therefore inserts a thousands comma and pads the single tenth out to two cents. The same call with Locale.GERMANY would instead print the amount with dotted grouping and the euro sign, since every symbol is locale-derived.

  5. Question 5

    What does this print? ```java import java.text.*; import java.util.*; public class Main { public static void main(String[] args) { MessageFormat mf = new MessageFormat("It''s {0}: set '{1}' to {1}", Locale.US); System.out.println(mf.format(new Object[] {"now", 42})); } } ```

    1. A. It's now: set 42 to 42

      Wrong: this treats the single quotes as meaningless decoration, substituting into the quoted {1} anyway - the most common MessageFormat mistake. The quotes are an escape and are consumed.

    2. B. It's now: set {1} to 42Correct answer

      Correct: a doubled single quote becomes one apostrophe (It's), a quoted {1} is emitted literally with no substitution, and the trailing {1} is the real placeholder filled with 42.

    3. C. It''s now: set {1} to 42

      Wrong: this handles the quoted section correctly but leaves the doubled quote doubled. A doubled single quote is not a literal pair of apostrophes; it collapses to exactly one.

    4. D. It's now: set '42' to 42

      Wrong: this assumes the quotes are literal characters that survive to the output and that substitution still occurs inside them. Quotes cannot be both data and an escape - here they are an escape and are consumed.

    Explanation

    Trace: in a `MessageFormat` pattern the single quote is the **escape character**, and it does two different jobs. - `It''s` — two adjacent single quotes are the way to write one literal apostrophe. Output: `It's`. - `{0}` — an ordinary argument slot, filled with the first argument: `now`. - `'{1}'` — a single quote *starts a quoted section* that ends at the next single quote. Everything inside is copied out literally and is **not** treated as a placeholder, and the quotes themselves are consumed. So this emits the four characters `{1}` and no substitution happens. - `{1}` — outside the quotes now, so this is a real placeholder and is filled with the second argument, the `Integer` 42. Result: `It's now: set {1} to 42`. (Passing `Locale.US` explicitly matters: `{1}` formats a number through the locale's `NumberFormat`, so the output would differ by locale if the number were large enough to be grouped.) Why the others are wrong: `It''s now: set {1} to 42` handles the quoted section correctly but leaves the doubled quote doubled. `''` is not a literal pair of apostrophes — it collapses to exactly one. `It's now: set 42 to 42` treats the single quotes as decoration with no meaning, substituting into `'{1}'` anyway and then dropping the quotes. That is the single most common `MessageFormat` misunderstanding, and in real code it is why an apostrophe accidentally left in a message file makes the placeholders after it stop expanding. `It's now: set '42' to 42` assumes the quotes are literal characters that survive to the output *and* that substitution still occurs inside them. Quotes cannot both be data and be an escape — here they are an escape, and they are consumed. Exam tip: in `MessageFormat`, `''` = one apostrophe, and `'...'` = a literal section where `{` and `}` lose their power. The reverse trap is the one that bites in production: a lone unmatched `'` opens a quoted section that runs to the end of the pattern, so every placeholder after it is emitted verbatim instead of being filled in.

  6. Question 6

    What does this print? ```java import java.text.*; import java.util.*; public class Main { public static void main(String[] args) { System.out.println(NumberFormat.getInstance(Locale.GERMANY).format(1234567.5)); } } ```

    1. A. 1,234,567.5

      This is Locale.US output; the German format swaps the separators, which is the entire point of the stem.

    2. B. 1.234.567,5Correct answer

      German formatting groups thousands with a period and uses a comma as the decimal, and the general-purpose instance shows only the fraction digits present without padding, giving 1.234.567,5.

    3. C. 1.234.567,50

      The forced two-digit fraction is currency behavior; plain getInstance has minimumFractionDigits 0 and pads nothing.

    4. D. 1234567,5

      Drops the grouping separators, but grouping is on by default for getInstance, so the thousands separators do appear.

    Explanation

    The general-purpose NumberFormat for Germany reverses the US symbols, using a period to group thousands and a comma as the decimal mark. Unlike a currency format it neither pads nor forces a fixed fraction count, so it prints only the single fraction digit the value carries. Grouping stays enabled by default, producing dotted thousands groups followed by a comma before the tenth.

  7. Question 7

    ResourceBundle.getBundle("Msg", Locale.GERMANY) selects Msg_de_DE.properties. The code then calls bundle.getString("farewell"), but that key exists only in the base bundle Msg.properties. What happens?

    1. A. MissingResourceException is thrown because the selected bundle lacks the key

      MissingResourceException fires only when no bundle in the parent chain has the key; here the base bundle supplies it.

    2. B. getString returns null

      getString never returns null; a missing key is always signalled by an exception, not a null.

    3. C. The value from Msg.properties is returned via the parent chainCorrect answer

      Each loaded bundle keeps a parent chain built from its less specific candidates (Msg_de_DE to Msg_de to Msg), and getString walks that chain upward, so a locally missing key is served by the base bundle.

    4. D. The empty string is returned

      An empty string comes back only if some bundle explicitly maps the key to an empty value, not when the key is simply absent.

    Explanation

    Bundle selection and key lookup are two separate fallbacks. Selection happens once in getBundle using the locale candidates, but each getString call then searches the loaded bundle's parent chain, from the most specific bundle up toward the base. A key absent from the selected bundle is therefore resolved from a less specific ancestor, and only exhausting the whole chain raises MissingResourceException; null is never returned.

  8. Question 8

    Which two statements about ResourceBundle are correct? (Choose two.)

    1. A. If no bundle exists for the requested locale, the default locale, or the base name itself, getBundle throws MissingResourceException rather than returning nullCorrect answer

      getBundle's contract is bundle-or-throw: after the requested locale's candidates, the default locale's candidates, and the base bundle all fail, it raises MissingResourceException rather than returning null.

    2. B. The base bundle is consulted before the default locale's bundles

      Inverts the order: the search is requested locale, then default locale, then base bundle, so the base is the last resort, not consulted before the default locale.

    3. C. A key absent from the selected bundle is searched up the parent chain before getString throws MissingResourceExceptionCorrect answer

      Key lookup delegates upward through the bundle's parent chain from most specific to base, and only when the root of the chain also lacks the key does getString throw.

    4. D. getString returns null when the key is not found in any bundle

      null is not part of the API contract; both bundle selection and key lookup signal failure with MissingResourceException, never a null return.

    Explanation

    Everything in ResourceBundle fails loudly rather than silently: neither bundle selection nor key lookup ever returns null, and exhausting the search raises MissingResourceException instead. Bundle selection proceeds from the requested locale to the default locale and only then to the base bundle, so the base is the last resort. Key lookup walks the loaded bundle's parent chain from most specific to base before it gives up.

Practise all 16 Localization questions

OCP Java SE 17 has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open OCP Java SE 17

Other topics in this pack