Java Tricky Programs (Output Prediction)
Every school has a teacher who loves trick questions: "Which is heavier, a kilo of cotton or a kilo of iron?" They aren't meant to fool you for fun; they test whether you really understand the idea or are only pattern-matching. Java interviews have their own trick questions: tiny programs whose output surprises people who haven't looked closely at how Java works. In this lesson, you will work through the most common ones, grouped by topic. Try to predict each answer before opening it, then run the program at the end of each section to check.
How to Approach an Output Question
- Read every character.
==versusequals,i++versus++i,'A'versus"A"change everything. - Evaluate step by step, left to right, writing down the type of every intermediate value.
- Check for compile errors first. Some "what does it print?" questions don't compile at all.
- Name the rule in your answer: "Integer caches -128 to 127", not just "false".
Puzzles About Equality
Puzzle 1. What does this print?
Integer a = 127, b = 127;
Integer c = 128, d = 128;
System.out.println(a == b);
System.out.println(c == d);Show the answer
true, then false. Autoboxing uses Integer.valueOf, which returns cached objects for -128 to 127, so a and b are the same object. 128 is outside the cache, so c and d are two different objects, and == compares references. Always compare wrapper values with equals.
Puzzle 2. What does this print?
String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s3.intern());Show the answer
true, false, true. Identical string literals share one object from the string pool. new String(...) always creates a new object. intern() returns the pooled copy.
Puzzle 3. What does this print?
System.out.println(0.1 + 0.2 == 0.3);
System.out.println(0.1 + 0.2);Show the answer
false, then 0.30000000000000004. double stores numbers in binary, and 0.1 and 0.2 have no exact binary form, so tiny rounding errors appear. Use BigDecimal for money, or compare doubles with a small tolerance.
public class EqualityCheck {
public static void main(String[] args) {
Integer a = 127, b = 127;
Integer c = 128, d = 128;
System.out.println(a == b);
System.out.println(c == d);
String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s3.intern());
System.out.println(0.1 + 0.2 == 0.3);
System.out.println(0.1 + 0.2);
}
}true
false
true
false
true
false
0.30000000000000004Puzzles About Operators and Types
Puzzle 4. What does this print?
System.out.println(1 + 2 + "3");
System.out.println("1" + 2 + 3);
System.out.println('A' + 1);
System.out.println("" + 'A' + 1);
System.out.println((char) ('A' + 1));Show the answer
33, 123, 66, A1, B. + works left to right: 1 + 2 is the number 3 before meeting a string. Once a String is involved, + joins text. A char plus an int is an int ('A' is 65), and casting 66 back to char gives B.
Puzzle 5. What does this print?
int i = 0;
i = i++;
System.out.println(i);Show the answer
0. i++ returns the old value (0) and then increases i to 1, but the assignment i = ... then stores the old value 0 back into i.
Puzzle 6. What does this print?
System.out.println(5 / 2);
System.out.println(5 / 2 * 2.0);
System.out.println(Math.round(-1.5));
System.out.println(Math.round(1.5));
System.out.println((byte) 200);
System.out.println(Math.abs(Integer.MIN_VALUE));Show the answer
2, 4.0, -1, 2, -56, -2147483648. 5 / 2 is integer division (2) before it is multiplied by 2.0. Math.round rounds half up, towards positive infinity, so -1.5 becomes -1. 200 doesn't fit in a byte (-128 to 127) and wraps to -56. Integer.MIN_VALUE has no positive int counterpart, so abs returns it unchanged.
public class OperatorCheck {
public static void main(String[] args) {
System.out.println(1 + 2 + "3");
System.out.println("1" + 2 + 3);
System.out.println('A' + 1);
System.out.println("" + 'A' + 1);
System.out.println((char) ('A' + 1));
int i = 0;
i = i++;
System.out.println(i);
System.out.println(5 / 2);
System.out.println(5 / 2 * 2.0);
System.out.println(Math.round(-1.5));
System.out.println(Math.round(1.5));
System.out.println((byte) 200);
System.out.println(Math.abs(Integer.MIN_VALUE));
}
}33
123
66
A1
B
0
2
4.0
-1
2
-56
-2147483648Puzzles About Methods and Classes
Puzzle 7. Which method is called?
static void show(Object o) { System.out.println("Object"); }
static void show(String s) { System.out.println("String"); }
show(null);Show the answer
String. Both methods accept null, and Java picks the most specific one. String is more specific than Object. If there were also a show(Integer) method, the call would be ambiguous and wouldn't compile.
Puzzle 8. What does this print?
class Parent {
static String who() { return "Parent"; }
String name() { return "Parent"; }
}
class Child extends Parent {
static String who() { return "Child"; }
String name() { return "Child"; }
}
Parent p = new Child();
System.out.println(p.who() + " " + p.name());Show the answer
Parent Child. Instance methods are overridden and chosen by the object's real type (Child). Static methods are hidden, not overridden, and chosen by the variable's declared type (Parent).
Puzzle 9. What does this method return?
static int value() {
try {
return 1;
} finally {
return 2;
}
}Show the answer
2. The finally block always runs, and a return inside it replaces the return from try. It would even swallow an exception thrown in try. Never return from finally.
public class MethodCheck {
static void show(Object o) { System.out.println("Object"); }
static void show(String s) { System.out.println("String"); }
static class Parent {
static String who() { return "Parent"; }
String name() { return "Parent"; }
}
static class Child extends Parent {
static String who() { return "Child"; }
@Override String name() { return "Child"; }
}
@SuppressWarnings("finally")
static int value() {
try {
return 1;
} finally {
return 2;
}
}
@SuppressWarnings("static-access")
public static void main(String[] args) {
show(null);
Parent p = new Child();
System.out.println(p.who() + " " + p.name());
System.out.println(value());
}
}String
Parent Child
2Puzzles About Collections and Strings
Puzzle 10. What does this print?
List<Integer> list = new ArrayList<>(List.of(10, 20, 30));
list.remove(1);
System.out.println(list);
list.remove(Integer.valueOf(10));
System.out.println(list);Show the answer
[10, 30], then [30]. remove(1) with an int calls remove(int index) and removes the element at index 1 (20). remove(Integer.valueOf(10)) calls remove(Object) and removes the value 10.
Puzzle 11. What does this print?
int[] numbers = {1, 2, 3};
System.out.println(Arrays.asList(numbers).size());
String name = "navika";
name.toUpperCase();
System.out.println(name);Show the answer
1, then navika. Arrays.asList takes objects, so an int[] becomes a single element (the array itself): use Integer[] or IntStream. Strings are immutable: toUpperCase() returns a new string, which is thrown away here.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CollectionCheck {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(List.of(10, 20, 30));
list.remove(1);
System.out.println(list);
list.remove(Integer.valueOf(10));
System.out.println(list);
int[] numbers = {1, 2, 3};
System.out.println(Arrays.asList(numbers).size());
String name = "navika";
name.toUpperCase();
System.out.println(name);
}
}[10, 30]
[30]
1
navikaPuzzles That Don't Compile
Puzzle 12. Which line fails to compile?
short s = 1;
s += 1; // line A
s = s + 1; // line BShow the answer
Line B. s + 1 is an int, and assigning an int to a short needs a cast. Line A compiles because compound assignment operators such as += include a hidden cast: s += 1 means s = (short) (s + 1).
Puzzle 13. Does this compile?
final int x;
System.out.println(x);Show the answer
No. A local variable must be definitely assigned before it is read, whether or not it is final. The error is "variable x might not have been initialized".
Interview Corner
Why should you never compare Integer objects with ==?
Because == compares references. It happens to work for values from -128 to 127, which are cached, and fails for others. Use equals or compare int values.
Why is returning from a finally block dangerous?
It replaces any value returned by try or catch and silently discards any exception thrown there, hiding real errors. Compilers warn about it.
Practice
- Easy: Predict, then run:
System.out.println(10 == 10.0);andSystem.out.println('a' + 'b'); - Harder: Predict, then run:
long micros = 24 * 60 * 60 * 1000 * 1000; System.out.println(micros);. Explain the result and fix it with one character.
Key Takeaways
Was this tutorial helpful?