Working with Java Data Types practice questions

From OCP Java SE 25 (1Z0-831) · 21 questions on this topic

Working with Java Data Types practice questions from OCP Java SE 25 (1Z0-831). This pack has 21 questions tagged Working with Java Data Types, 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 Working with Java Data Types

  1. Question 1

    Which two statements about text handling in Java are correct? (Choose two.)

    1. A. String is immutable, so replace, toUpperCase, and strip each return a new String and leave the original unchangedCorrect answer

      Correct: String is immutable, so replace, toUpperCase, strip and every other apparent 'mutator' return a brand-new String and leave the original untouched.

    2. B. StringBuilder.reverse() returns a new StringBuilder and leaves the original builder unchanged

      StringBuilder.reverse() reverses the characters in place and returns the same builder (this), not a new object; in-place mutation is exactly what distinguishes StringBuilder from String.

    3. C. As of Java 25, CharSequence declares getChars(int, int, char[], int) as a default method, so every CharSequence implementation exposes itCorrect answer

      Correct: as of Java 25, CharSequence declares getChars(int, int, char[], int) as a default method, so every CharSequence implementation (String, StringBuilder, CharBuffer) exposes it, even through a CharSequence reference.

    4. D. The == operator on two String variables compares their character contents, so "ab" == "ab" being true proves == checks characters

      == on two String references compares identity, not content; "ab" == "ab" is true only because both literals are interned to one pooled object, not because == inspects characters. Use equals to compare content.

    Explanation

    String is immutable, so its transforming methods return new instances and never change the original, whereas StringBuilder mutates in place and returns the same builder. As of Java 25 CharSequence provides getChars as a default method available to every implementation through the interface. Content comparison of strings requires equals; == tests only reference identity, which can coincidentally hold for interned literals.

  2. Question 2

    Three overloads of `show` are in scope and the argument passed is an `int`. What does this program print? ```java public class Main { static void show(long value) { System.out.println("long"); } static void show(Integer value) { System.out.println("Integer"); } static void show(Object value) { System.out.println("Object"); } public static void main(String[] args) { int x = 5; show(x); } } ```

    1. A. Object

      Believes a primitive must be boxed before any reference parameter applies and that Object is the universal fallback; even in the boxing phase Object would lose to Integer, and boxing is only reached after widening fails.

    2. B. Integer

      Believes the compiler prefers the most exact-looking Integer match; boxing is a later phase than widening, so the merely-widening candidate show(long) wins — remove that overload and the call really does print Integer.

    3. C. longCorrect answer

      Overload resolution phase one allows widening primitive conversion but no boxing, and int widens to long, so show(long) is applicable immediately and is chosen; the Integer and Object overloads need boxing, a phase the compiler never reaches — long.

    4. D. Compilation fails: the call `show(x)` is ambiguous

      Believes three int-accepting candidates leave the compiler no way to choose; the phase ordering is the tie-break, so an ambiguity error needs two candidates applicable in the same phase with neither more specific.

    Explanation

    Trace: overload resolution runs in three ordered phases and stops at the first phase that finds an applicable method. Phase one allows only strict invocation — subtyping and widening *primitive* conversion, but no boxing and no varargs. Widening `int` to `long` is permitted there, so `show(long)` is applicable in phase one and is chosen immediately. The `Integer` and `Object` overloads would need boxing, which is only considered in phase two — a phase the compiler never reaches. The program prints `long`. Why the others are wrong: `Integer` encodes the belief that the compiler prefers the most "exact-looking" match, since an `int` boxes to an `Integer` and nothing else. Boxing is a later phase than widening, so a merely-widening candidate always beats a boxing one. Delete the `long` overload and this call really does print `Integer` — that is the shape most people are remembering. `Object` encodes the belief that a primitive must be boxed before any reference parameter can accept it and that `Object` is the universal fallback. Even inside the boxing phase `Object` would lose to `Integer`, because the more specific applicable method wins; `Object` is only reached when nothing else fits. `Compilation fails: the call `show(x)` is ambiguous` encodes the belief that three candidates all able to accept an `int` leave the compiler with no way to choose. The phase ordering *is* the tie-break, so an ambiguity error needs two candidates applicable in the *same* phase with neither more specific. Exam tip: the priority ladder for a primitive argument is widen, then box, then varargs — and the compiler never mixes a widening with a boxing on the same argument. That last point kills a favourite trap: with only a `show(Long)` overload in scope, `show(x)` where `x` is an `int` does **not** compile, because reaching `Long` would demand a widening *and* a boxing.

  3. Question 3

    Both locals below are declared with `var` and initialised from a wrapper parse method. What is printed? ```java public class Main { public static void main(String[] args) { var flag = Boolean.parseBoolean("TRUE"); var n = Integer.parseInt("017"); System.out.println(flag + " " + (n + 1)); } } ```

    1. A. false 18

      Assumes parseBoolean matches case-sensitively; it compares ignoring case, so an all-caps TRUE yields true.

    2. B. true 16

      Assumes the leading zero makes the string octal; parseInt always uses radix 10, so the value is 17 and adding one gives 18.

    3. C. true 18Correct answer

      parseBoolean ignores case so the flag is true, and parseInt parses in radix 10 so the value is 17, making the sum 18.

    4. D. Compilation fails

      Assumes var cannot infer here; both initialisers have a definite standalone type, so inference succeeds.

    Explanation

    Boolean.parseBoolean compares its argument to the text true, ignoring case. Integer.parseInt of a string always parses in decimal, so a leading zero is not an octal prefix, a convention that applies only to source literals. var infers each local's type from an initializer that has a definite standalone type.

  4. Question 4

    What is printed? ```java public class Main { public static void main(String[] args) { int r = 2 + 3 * 4 - 10 % 4; System.out.println(r); } } ```

    1. A. 2

      Evaluates strictly left to right ignoring precedence: ((((2+3)*4)-10)%4) = 2, the classic 'no precedence' mistake.

    2. B. 12Correct answer

      * and % bind tighter than + and -, so 3*4 = 12 and 10%4 = 2, leaving 2 + 12 - 2 = 12.

    3. C. 13

      Uses 10 % 4 = 1; the remainder of 10 divided by 4 is 2, not 1.

    4. D. 0

      Applies % last, computing (2 + 3*4 - 10) % 4 = 4 % 4 = 0; but % has the same precedence as *, not lower than -.

    Explanation

    The multiplicative operators (*, /, %) bind tighter than the additive operators (+, -), and operators sharing a precedence level evaluate left to right. Mentally inserting the implicit parentheses — 2 + (3*4) - (10%4) — reveals the correct evaluation order before any addition is performed.

  5. Question 5

    What does this program print? ```java public class Main { public static void main(String[] args) { Integer a = 1000, b = 1000; int c = 1000; System.out.println((a == b) + " " + (a == c)); } } ```

    1. A. false trueCorrect answer

      1000 is outside the guaranteed Integer cache (-128..127), so a and b are distinct objects and the reference test is false; but the second comparison has a primitive operand, so a is unboxed and 1000 == 1000 is true (JLS 25 5.1.7).

    2. B. true true

      Would require 1000 to be cached; the guaranteed cache stops at 127, so the two wrappers are not the same object and the reference comparison is false.

    3. C. false false

      Ignores that comparing a wrapper with a primitive unboxes the wrapper, making the second comparison a value comparison that is true.

    4. D. true false

      Reverses both results; the wrapper-to-wrapper comparison is false and the wrapper-to-primitive comparison is true, not the other way around.

    Explanation

    == between two wrapper references is an identity test, and autoboxing only caches values in the range -128..127, so equal wrappers outside that range are distinct objects and compare unequal. When == has one wrapper operand and one primitive operand, the wrapper is unboxed and the comparison is made by numeric value instead.

  6. Question 6

    What is the output? ```java public class Main { public static void main(String[] args) { StringBuilder sb = new StringBuilder("computer"); sb.replace(0, 3, "AM").deleteCharAt(2).append("!"); System.out.println(sb); } } ```

    1. A. AMuter!Correct answer

      replace(0, 3, 'AM') turns 'computer' into 'AMputer', deleteCharAt(2) removes the 'p' giving 'AMuter', and append('!') yields 'AMuter!'; each call mutates and returns the same builder.

    2. B. AMputer!

      Ignores deleteCharAt(2); each call in the chain runs on the same builder, so that step is not skipped.

    3. C. AMpter!

      Deletes index 3 ('u') instead of index 2 ('p'); deleteCharAt(2) targets the character at index 2.

    4. D. computerAM!

      Treats replace as an append; replace(0, 3, ...) overwrites the first three characters in place rather than adding text to the end.

    Explanation

    StringBuilder methods mutate the receiver and return this, so every call in a chain operates on the result of the previous one rather than on a fresh copy. replace(start, end, str) uses a half-open range, replacing start up to but not including end, and deleteCharAt removes the single character at the given index.

  7. Question 7

    An `Integer` and a `Long` both hold the numeric value 5, and each is compared with `equals` against a literal of the other's width. What does this program print? ```java public class Main { public static void main(String[] args) { Integer i = 5; Long l = 5L; System.out.println(i.equals(5L) + " " + l.equals(5)); } } ```

    1. A. Compilation fails: `Integer.equals` cannot accept a `long` argument

      Assumes equals is overloaded per type; there is one equals(Object), and any primitive boxes to fit it, so both calls compile cleanly — which is exactly why the bug is a silent false rather than a compile error.

    2. B. false falseCorrect answer

      Correct: each literal boxes to the wrapper of its own width, and Integer.equals demands an Integer while Long.equals demands a Long, so both cross-type comparisons return false without comparing numbers.

    3. C. true false

      Assumes primitive widening (int to long) applies to the boxed argument, so the first call succeeds and the second fails; no numeric promotion happens — the parameter is Object, so each literal boxes to its own wrapper type.

    4. D. true true

      Assumes equals on wrappers compares numeric value the way == does on primitives; wrapper equals is type-sensitive first, so a Long holding 5 is never equal to an Integer holding 5.

    Explanation

    Trace: every wrapper's `equals` takes an `Object`, so the argument is autoboxed before the call. `i.equals(5L)` boxes the `long` literal into a `Long` and asks `Integer.equals(Long)`; `Integer.equals` first checks `instanceof Integer`, the argument is a `Long`, so it returns `false` without ever comparing numbers. `l.equals(5)` is the mirror image: the `int` literal boxes to an `Integer`, and `Long.equals` demands a `Long`. Both comparisons are false, so the program prints `false false`. Why the others are wrong: `true true` encodes the belief that `equals` on wrappers compares numeric value the way `==` does on primitives. Wrapper `equals` is type-sensitive first and value-sensitive second — a `Long` holding 5 is never equal to an `Integer` holding 5. `true false` encodes the belief that the widening that applies to primitives (`int` promotes to `long`) also applies to the boxed argument, so the first call succeeds and the second, which would need narrowing, fails. No numeric promotion happens at all here: the parameter type is `Object`, so each literal is boxed to the wrapper of its own declared width and nothing is widened. `Compilation fails: `Integer.equals` cannot accept a `long` argument` encodes the belief that `equals` is overloaded per type. There is one `equals(Object)`, and any primitive boxes to fit it, so both calls compile cleanly — this is precisely why the bug is a silent `false` at runtime instead of a compiler error. Exam tip: cross-wrapper `equals` is always `false`, whatever the numbers say. Compare the primitive values instead (`i.intValue() == l.longValue()` is `true` here). The reverse trap is same-type `equals`: `i.equals(5)` is `true`, because the `int` literal boxes to an `Integer`.

  8. Question 8

    What does this program print? ```java public class Main { public static void main(String[] args) { char c = 'A'; int r = c + 5; System.out.println(r); } } ```

    1. A. F

      Assumes the result stays a char and prints the glyph for code point 70; but the sum has type int and is assigned to an int, so the decimal number prints, not a character.

    2. B. 70Correct answer

      In c + 5, binary numeric promotion widens the char 'A' (code point 65) to int, so the arithmetic is 65 + 5 = 70, an int, which is stored in r and printed as 70 (JLS 25 5.6).

    3. C. A5

      Treats + as string concatenation, but neither operand is a String, so + is interpreted as arithmetic addition rather than concatenation.

    4. D. Compilation fails: char cannot be added to an int

      A char participates in arithmetic by promoting to int, so char + int is a perfectly legal int expression; nothing fails to compile.

    Explanation

    Any char used in an arithmetic expression undergoes binary numeric promotion to its int code point, so char + int yields an int. When that int value is printed directly, the decimal number appears; only casting back with (char) would display a glyph. Here the result is assigned to an int and printed, so the number is shown.

Practise all 21 Working with Java Data Types questions

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

Open OCP Java SE 25

Other topics in this pack