Working with Java Data Types practice questions

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

Working with Java Data Types practice questions from OCP Java SE 21 (1Z0-830). 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

    What does the following program print to standard output? ```java public class Main { public static void main(String[] args) { System.out.println(Math.round(2.5) + Math.round(-2.5)); } } ```

    1. A. 0

      Assumes Math.round uses symmetric rounding: half-away-from-zero gives 3 + (−3) = 0, and half-to-even (banker's rounding) gives 2 + (−2) = 0. Java's Math.round always rounds halves toward positive infinity, which is asymmetric around the midpoint.

    2. B. `1.0`

      Assumes Math.round(double) returns a double; it actually returns long. System.out.println(1L) prints '1', not '1.0'.

    3. C. 1Correct answer

      Math.round(double) is specified as (long)Math.floor(a + 0.5d). For 2.5: floor(3.0) = 3L; for −2.5: floor(−2.0) = −2L. The sum 3 + (−2) = 1 is printed as the long value 1 (Javadoc: Math.round(double)).

    4. D. `-1`

      Results from applying Math.floor directly without the +0.5 offset: floor(2.5) = 2 and floor(−2.5) = −3, summing to −1. Math.round adds 0.5 before flooring, which shifts the midpoint result upward.

    Explanation

    Java's Math.round(double) is defined as (long)Math.floor(a + 0.5d), which rounds ties toward positive infinity — not symmetrically. For 2.5 the formula yields floor(3.0) = 3L, and for −2.5 it yields floor(−2.0) = −2L, so the sum is 1. Candidates who expect symmetric half-away-from-zero rounding (3 + (−3) = 0) or half-to-even/banker's rounding (2 + (−2) = 0) arrive at 0; confusing Math.round with a bare Math.floor (floor(2.5) = 2, floor(−2.5) = −3, sum = −1) is another trap. Because Math.round(double) returns long rather than double, the result prints as '1', not '1.0'.

  2. Question 2

    The number of microseconds in a day is computed and stored in a long. Choose the result of compiling and running this program. ```java public class Main { public static void main(String[] args) { long micros = 24 * 60 * 60 * 1000 * 1000; System.out.println(micros); } } ```

    1. A. 500654080Correct answer

      Every operand is an int literal, so the product is computed in 32-bit int arithmetic; 86,400,000,000 does not fit, so it wraps modulo 2^32 to 500654080, and only then is the broken int widened to long and assigned.

    2. B. An ArithmeticException is thrown at runtime

      Assumes Java traps integer overflow. +, - and * wrap silently; only division/remainder by zero throws ArithmeticException (Math.multiplyExact is the method that throws on overflow).

    3. C. 86400000000

      The mathematically correct value, which you get only from `24L * 60 * 60 * 1000 * 1000` where one L promotes the whole chain to long arithmetic. The stem has no L, so the int product wraps first.

    4. D. Compilation fails: the expression overflows int and cannot be assigned to long

      Confuses runtime overflow with the compile-time literal check. A bare literal like 10_000_000_000 is rejected by javac, but an int EXPRESSION that overflows at runtime is legal — javac constant-folds it and hands over the wrapped value.

    Explanation

    Trace: every operand — `24`, `60`, `60`, `1000`, `1000` — is an int literal, so the whole product is evaluated in 32-bit int arithmetic. The mathematical value 86_400_000_000 does not fit in an int, so the multiplication silently wraps modulo 2^32 and yields `500654080`. Only THEN is that already-broken int widened to long and assigned to `micros`. The declared type of the variable never reaches back into the expression. Why the others are wrong: `86400000000` is the mathematically correct answer, and it is what you get from `24L * 60 * 60 * 1000 * 1000` — one `L` on the first operand promotes the whole chain to long arithmetic. The stem has no `L`. `Compilation fails: the expression overflows int...` confuses runtime overflow with the compile-time literal check. `10_000_000_000` as a bare literal is rejected by javac, but an int *expression* that overflows at runtime is perfectly legal — javac only constant-folds it and hands over the wrapped value. `An ArithmeticException is thrown at runtime` assumes Java traps integer overflow. It does not: `+`, `-` and `*` wrap around silently. Only division/remainder by zero throws ArithmeticException. (`Math.multiplyExact` is the method that throws on overflow.) Exam tip: promotion follows the OPERANDS, never the assignment target. The moment you see a long (or a wide result) built from int literals, ask whether the intermediate product fits in 32 bits — and if it does not, look for the `L` suffix. Same trap in reverse: `long ms = 1000L * 60 * 60 * 24 * 365;` is safe because the first operand drags everything to long.

  3. Question 3

    A CSV line is split twice — once with the one-argument split and once with an explicit negative limit. Determine the exact output. ```java public class Main { public static void main(String[] args) { String csv = "a,b,,c,"; String[] parts = csv.split(","); System.out.println(parts.length + " " + String.join("|", parts) + " " + csv.split(",", -1).length); } } ```

    1. A. 5 a|b||c| 5

      Assumes the one-argument split keeps trailing empty strings; the zero-limit default discards them, so the first length is 4, not 5.

    2. B. 4 a|b||c 4

      Gets the default split right but forgets that a negative limit disables trailing-empty removal, so the second count should be 5, not 4.

    3. C. 4 a|b||c 5Correct answer

      The one-argument split uses limit 0, dropping the trailing empty field (giving four parts, joined a|b||c) while keeping the interior empty; splitting with limit -1 retains the trailing empty for length 5.

    4. D. 3 a|b|c 5

      Assumes every empty field is dropped; only trailing empties are removed by the default, so the interior empty between the two commas survives.

    Explanation

    String.split with no limit argument behaves as if the limit were zero, applying the pattern as many times as possible and then discarding trailing empty strings while preserving empties that fall between real fields. Supplying a negative limit turns that trimming off, so trailing empty fields are retained and the resulting array is longer.

  4. Question 4

    Three compound assignments are applied to three different primitive types. Choose the result of compiling and running the program. ```java public class Main { public static void main(String[] args) { int i = 7; i /= 2; char c = 'A'; c += 1.9; short s = 10; s *= 1.5; System.out.println(i + " " + c + " " + s); } } ```

    1. A. 3 66 15

      Prints 66 for the char, but the variable is still a char, so it is printed as the character 'B', not as its numeric code 66.

    2. B. 3 B 15Correct answer

      Integer division gives 7/2 = 3; the implicit narrowing cast turns 'A'(65)+1.9 = 66.9 into char 66 ('B') by truncation, and 10*1.5 = 15.0 into short 15.

    3. C. 3 C 15

      Assumes the char result rounds up; narrowing conversion truncates toward zero, so 66.9 becomes 66 ('B'), not 67 ('C').

    4. D. Compilation fails

      Assumes the double-to-char and double-to-short assignments need an explicit cast; a compound assignment carries an implicit narrowing cast, so they compile.

    Explanation

    A compound assignment applies an implicit narrowing cast back to the left-hand type, so mixing in a double operand compiles without an explicit cast where a plain assignment would not. That narrowing truncates toward zero rather than rounding, integer division discards the remainder, and a char variable still prints as its character even after arithmetic.

  5. Question 5

    What does the following program print? ```java public class Main { public static void main(String[] args) { int x = Integer.MAX_VALUE; long y = x + 1; System.out.println(y); } } ```

    1. A. 2147483648

      Assumes the `long` assignment target causes `x + 1` to be evaluated in long arithmetic, preventing overflow. In Java the result type of `+` depends only on the operand types: both `x` and the literal `1` are `int`, so the addition is computed as int before any widening to `long` takes place.

    2. B. -2147483648Correct answer

      `x + 1` is an `int + int` expression whose result type is `int`. Adding 1 to `Integer.MAX_VALUE` (2147483647) overflows and wraps to `Integer.MIN_VALUE` (-2147483648) under two's-complement rules (JLS §15.18.2). That `int` value is then widened losslessly to `long`, so `println` prints -2147483648.

    3. C. 2147483647

      Assumes integer overflow saturates at `Integer.MAX_VALUE`, as in languages with saturating arithmetic. Java's integer types use two's-complement with no saturation: overflow wraps silently to the minimum value of the type.

    4. D. Compilation error

      Assumes the Java compiler detects and rejects potential integer overflow. The compiler performs no run-time overflow analysis; integer overflow is a silent, fully defined behaviour that occurs only at run time and is never a compile-time error.

    Explanation

    The type of a binary `+` expression is determined by the types of its operands, never by the variable receiving the result. Because both `x` and the literal `1` are `int`, `x + 1` is computed entirely as `int` arithmetic: adding 1 to `Integer.MAX_VALUE` (2147483647) overflows and wraps to `Integer.MIN_VALUE` (-2147483648) under two's-complement rules (JLS §15.18.2). The `int` result is then widened to `long` through a lossless primitive widening conversion, so -2147483648 is what is stored in `y` and printed. Believing the `long` target promotes the operands leads to predicting 2147483648; expecting saturation behaviour leads to 2147483647; conflating compile-time type checking with run-time arithmetic bounds leads to expecting a compilation error.

  6. Question 6

    Each local variable below is declared with var. Identify what the program prints. ```java public class Main { public static void main(String[] args) { var count = 5; var price = 2.5; var total = count * price; Double boxed = total; System.out.println(total + " " + boxed.equals(12.5)); } } ```

    1. A. 12 true

      Assumes the product takes the int operand's type; binary numeric promotion widens the int to double, so the product is a double 12.5, not 12.

    2. B. 12.5 false

      Assumes the equals call fails across wrapper and primitive; the literal is autoboxed to a wrapper and its equals compares the wrapped values, yielding true.

    3. C. Compilation fails

      A local declared with var and an initializer is legal, so nothing here prevents compilation.

    4. D. 12.5 trueCorrect answer

      var infers int, double, then double for the product (12.5); assigning it to a wrapper autoboxes it, and the wrapper equals autoboxes the literal and compares equal, giving true.

    Explanation

    var infers each local's type from its initializer, and binary numeric promotion widens an int operand to double when it is combined with a double, so an integer-times-double product is itself a double. Assigning a double to a wrapper autoboxes it, and a wrapper's equals compares the boxed values after autoboxing the argument, so equal numeric values compare equal.

  7. Question 7

    Consider the following code. What does it print? ```java public class Main { public static void main(String[] args) { String s = "abcdef"; System.out.println(s.substring(2, 5)); } } ```

    1. A. cdeCorrect answer

      substring(2, 5) extracts the half-open range [2, 5): the characters at indices 2, 3, and 4 — 'c', 'd', 'e' — yielding "cde" (String.substring(int,int) Javadoc).

    2. B. cdef

      Treats endIndex 5 as inclusive, which would add the character at index 5 ('f'). The endIndex parameter is always exclusive in Java's substring — a half-open interval consistent with Java collections throughout.

    3. C. bcde

      Assumes indices are 1-based (as in SQL and some scripting languages), shifting the window left by one so it starts at 'b' and ends at 'e'. Java String indices are 0-based.

    4. D. Throws `StringIndexOutOfBoundsException`

      No exception is thrown. The contract requires 0 <= beginIndex <= endIndex <= length; with beginIndex=2, endIndex=5, and length=6, all three inequalities are satisfied.

    Explanation

    String.substring(int beginIndex, int endIndex) follows the half-open interval convention used throughout the Java standard library: the character at beginIndex is included and the character at endIndex is excluded. For "abcdef" (indices 0–5), substring(2, 5) selects indices 2, 3, and 4 — the characters 'c', 'd', 'e' — and returns "cde". The endIndex-inclusive distractor adds the character at index 5. The 1-based-indexing distractor reflects a habit from languages like SQL or Lua where string functions count from 1. No exception is thrown because all three boundary constraints (0 ≤ 2 ≤ 5 ≤ 6) are satisfied.

  8. Question 8

    A padded string is stripped, measured, tested for blankness, and searched. What is the exact output? ```java public class Main { public static void main(String[] args) { String s = " Java 21 "; System.out.println("[" + s.strip() + "] " + s.length() + " " + s.isBlank() + " " + s.trim().indexOf("21")); } } ```

    1. A. [Java 21] 7 false 5

      Assumes strip() mutates `s`. String is immutable and every method returns a new object, so s.length() is still measured on the 11-character padded original.

    2. B. [Java 21] 11 false 7

      Searches the untrimmed string, where "21" starts at index 7. The code calls indexOf on s.trim() ("Java 21"), where "21" is at index 5.

    3. C. [Java 21] 11 true 5

      Misreads isBlank() as 'has leading or trailing whitespace'. isBlank() asks whether the string is empty or whitespace-only; `s` holds real letters, so it is false.

    4. D. [Java 21] 11 false 5Correct answer

      strip() returns a new trimmed string ([Java 21]) without changing `s` (length 11); isBlank() is false because `s` has letters; s.trim().indexOf("21") is 5 (J=0, a=1, v=2, a=3, space=4, 2=5).

    Explanation

    Trace: `strip()` returns a NEW string with the leading and trailing whitespace removed, so `[" + s.strip() + "]` renders `[Java 21]`. It does not touch `s`, which is still the original 11-character literal (two spaces + `Java 21` (7 chars) + two spaces), so `s.length()` is `11`. `isBlank()` is `true` only when the string is empty or contains nothing but whitespace; `s` holds real letters, so it is `false`. `s.trim()` yields `Java 21`, in which `2` sits at index 5 (J=0, a=1, v=2, a=3, space=4, 2=5), so `indexOf("21")` is `5`. Why the others are wrong: `[Java 21] 7 false 5` assumes `strip()` mutates `s` — String is immutable, and every String method returns a new object; `s.length()` is still measured on the padded original. `[Java 21] 11 true 5` misreads `isBlank()` as 'has leading or trailing whitespace'. It actually asks whether the string is whitespace-only. `[Java 21] 11 false 7` searches the untrimmed string, where `21` starts at index 7. The code calls `indexOf` on `s.trim()`, not on `s`. Exam tip: no String method ever modifies the receiver; the return value is the whole point. `strip()` (Unicode-aware, Java 11+) and `trim()` (strips anything <= U+0020) differ only around exotic whitespace — for ASCII spaces they agree, and both were 7 characters here.

Practise all 21 Working with Java Data Types questions

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

Open OCP Java SE 21

Other topics in this pack