Gotcha roundup I — values & flow
Integer division, overflow, numeric promotion, compound-assignment casts, == on Strings and wrappers, switch fall-through.
Quick-fire traps: values and flow control
OCP questions deliberately use these patterns to test precise language knowledge. Drill each one until the answer is instant.
### Integer division truncates
int a = 7, b = 2;
System.out.println(a / b); // 3 — not 3.5
System.out.println(a % b); // 1 — the remainder
double d = 7 / 2; // 3.0 — both operands are int!
double e = 7 / 2.0; // 3.5 — one double forces double division
Assigning an integer division result to a double variable does not change the division — the operation happens first, then the int 3 is widened to 3.0.
### Overflow wraps silently
int max = Integer.MAX_VALUE; // 2_147_483_647
System.out.println(max + 1); // -2_147_483_648 — wraps, no exception
Java does not throw on integer overflow. The bits wrap around. Use long for large values or Math.addExact to detect overflow.
### Numeric promotion: byte + byte = int
byte a = 10, b = 20;
// byte c = a + b; // compile error — result is int
byte c = (byte)(a + b); // explicit cast required
a += b; // compound assignment hides the cast — compiles
byte, short, and char are promoted to int before arithmetic. The result is int, not byte, so storing it back needs a cast — unless you use compound assignment, which inserts the cast silently.
### == on Strings and wrappers
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true — same pool reference
System.out.println(s1 == s3); // false — s3 is a new heap object
System.out.println(s1.equals(s3)); // true — compares content
String literals are interned (pooled), so two literals with the same content share one object. new String(...) always allocates a new object. Always use .equals for String value comparison.
The same trap applies to Integer (and other wrapper) objects. Java caches Integer instances for values −128 to 127:
Integer x = 100, y = 100;
System.out.println(x == y); // true — cached
Integer a = 200, b = 200;
System.out.println(a == b); // false — outside cache range
Outside that range, two autoboxed values with the same int are different objects. Use .equals or .intValue() == to compare wrapper values safely.
### switch fall-through
int day = 2;
switch (day) {
case 1: System.out.println("Monday");
case 2: System.out.println("Tuesday"); // executes
case 3: System.out.println("Wednesday"); // also executes — fall-through!
break;
case 4: System.out.println("Thursday"); // does not execute
}
A switch statement falls through from one case to the next unless a break exits. The OCP exam presents fall-through code and asks for the output — trace every case until you hit a break. The switch expression (Java 14+, arrow syntax) does not fall through and is preferred in new code.