Skip to main content

🎯 Top 50 Most Asked Tricky Java Output Problems

🟢 Beginner Level (1-15)

1️⃣ String Pool Gotcha

public class Test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}

Output:

false
true

Explanation: == checks reference equality, .equals() checks value equality.


2️⃣ Integer Caching

public class Test {
public static void main(String[] args) {
Integer a = 127;
Integer b = 127;
System.out.println(a == b);

Integer c = 128;
Integer d = 128;
System.out.println(c == d);
}
}

Output:

true
false

Explanation: Java caches Integer objects from -128 to 127.


3️⃣ Pre/Post Increment

public class Test {
public static void main(String[] args) {
int i = 5;
System.out.println(i++ + ++i);
}
}

Output:

12

Explanation: i++ uses 5 then increments to 6, ++i increments to 7 then uses it → 5+7=12.


4️⃣ Static Block Execution Order

class A {
static { System.out.print("A"); }
}

class B extends A {
static { System.out.print("B"); }
}

public class Test {
public static void main(String[] args) {
B obj = new B();
}
}

Output:

AB

Explanation: Parent static block executes before child static block.


5️⃣ Overloaded Methods & Null

public class Test {
public static void main(String[] args) {
print(null);
}

static void print(Object o) { System.out.println("Object"); }
static void print(String s) { System.out.println("String"); }
}

Output:

String

Explanation: Null matches the most specific type (String is more specific than Object).


6️⃣ Polymorphism + Overloading

class A { }
class B extends A { }

public class Test {
static void show(A a) { System.out.println("A"); }
static void show(B b) { System.out.println("B"); }

public static void main(String[] args) {
A obj = new B();
show(obj);
}
}

Output:

A

Explanation: Overloaded method is chosen at compile-time based on reference type, not runtime type.


7️⃣ String Immutability

public class Test {
public static void main(String[] args) {
String s = "abc";
s.concat("def");
System.out.println(s);
}
}

Output:

abc

Explanation: String is immutable; concat() creates a new string, but result is not stored.


8️⃣ Arrays.asList() Trap

import java.util.*;

public class Test {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
list.remove(2);
System.out.println(list);
}
}

Output:

UnsupportedOperationException

Explanation: Arrays.asList() returns a fixed-size list backed by an array.


9️⃣ Floating Point Precision

public class Test {
public static void main(String[] args) {
System.out.println(0.1 + 0.2 == 0.3);
}
}

Output:

false

Explanation: Binary floating-point representation cannot exactly represent 0.1 and 0.2.


🔟 Final Reference Mutation

import java.util.*;

public class Test {
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("A");
System.out.println(list);
}
}

Output:

[A]

Explanation: final prevents reassignment of the reference, not mutation of the object.


1️⃣1️⃣ Constructor Chaining

class Parent {
Parent() { System.out.print("1"); }
}

class Child extends Parent {
Child() { System.out.print("2"); }
}

public class Test {
public static void main(String[] args) {
new Child();
}
}

Output:

12

Explanation: Parent constructor is called before child constructor.


1️⃣2️⃣ Division by Zero

public class Test {
public static void main(String[] args) {
System.out.println(10 / 0);
System.out.println(10.0 / 0);
}
}

Output:

ArithmeticException: / by zero

Explanation: Integer division by zero throws exception, but line 2 never executes.


1️⃣3️⃣ String Concatenation

public class Test {
public static void main(String[] args) {
System.out.println(1 + 2 + "3");
System.out.println("1" + 2 + 3);
}
}

Output:

33
123

Explanation: Left-to-right evaluation; numbers add first, then concatenate in line 1; all concatenate in line 2.


1️⃣4️⃣ Boolean Auto-boxing

public class Test {
public static void main(String[] args) {
Boolean b1 = true;
Boolean b2 = true;
Boolean b3 = new Boolean(true);
System.out.println(b1 == b2);
System.out.println(b1 == b3);
}
}

Output:

true
false

Explanation: Boolean caches true and false, but new Boolean() creates a new object.


1️⃣5️⃣ Switch Fall-through

public class Test {
public static void main(String[] args) {
int x = 1;
switch(x) {
case 1: System.out.print("A");
case 2: System.out.print("B");
default: System.out.print("C");
}
}
}

Output:

ABC

Explanation: No break statements cause fall-through to all subsequent cases.


🟡 Intermediate Level (16-35)

1️⃣6️⃣ Method Overriding with Covariant Return

class Parent {
Object test() { return "Parent"; }
}

class Child extends Parent {
String test() { return "Child"; }
}

public class Test {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.test());
}
}

Output:

Child

Explanation: Covariant return types allow child class to return a subtype. Runtime polymorphism applies.


1️⃣7️⃣ Static Method Hiding

class Parent {
static void test() { System.out.println("Parent"); }
}

class Child extends Parent {
static void test() { System.out.println("Child"); }
}

public class Test {
public static void main(String[] args) {
Parent p = new Child();
p.test();
}
}

Output:

Parent

Explanation: Static methods are hidden, not overridden. Called based on reference type.


1️⃣8️⃣ Exception in Constructor

class A {
A() throws Exception {
throw new Exception("Error");
}
}

public class Test {
public static void main(String[] args) {
try {
new A();
} catch(Exception e) {
System.out.println("Caught");
}
}
}

Output:

Caught

Explanation: Constructor can throw checked exceptions if declared.


1️⃣9️⃣ Array Covariance

public class Test {
public static void main(String[] args) {
Object[] arr = new String[3];
arr[0] = "Hello";
arr[1] = 100;
}
}

Output:

ArrayStoreException

Explanation: Arrays are covariant, but runtime type checking prevents storing wrong type.


2️⃣0️⃣ Ternary Operator Type Promotion

public class Test {
public static void main(String[] args) {
char c = 'a';
int i = 97;
System.out.println(true ? c : i);
System.out.println(false ? c : i);
}
}

Output:

a
97

Explanation: Result type is promoted to common type (int), but char 'a' prints as 'a'.


2️⃣1️⃣ StringBuilder vs StringBuffer

public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb);
}
}

Output:

Hello World

Explanation: StringBuilder is mutable and modifies the original object.


2️⃣2️⃣ Multiple Inheritance Diamond

interface A {
default void test() { System.out.println("A"); }
}

interface B {
default void test() { System.out.println("B"); }
}

class C implements A, B {
public void test() { System.out.println("C"); }
}

public class Test {
public static void main(String[] args) {
new C().test();
}
}

Output:

C

Explanation: Class method overrides default methods from interfaces.


2️⃣3️⃣ ArrayList Remove by Index vs Value

import java.util.*;

public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
list.remove(2);
list.remove(Integer.valueOf(2));
System.out.println(list);
}
}

Output:

[1, 4]

Explanation: First removes index 2 (value 3), then removes value 2.


2️⃣4️⃣ NaN Comparison

public class Test {
public static void main(String[] args) {
double d = 0.0 / 0.0;
System.out.println(d == d);
System.out.println(Double.isNaN(d));
}
}

Output:

false
true

Explanation: NaN is not equal to itself; use isNaN() to check.


2️⃣5️⃣ Instance Initializer Block

class Test {
{
System.out.print("A");
}

Test() {
System.out.print("B");
}

{
System.out.print("C");
}

public static void main(String[] args) {
new Test();
}
}

Output:

ACB

Explanation: Instance initializer blocks run before constructor, in order of appearance.


2️⃣6️⃣ Short Circuit Evaluation

public class Test {
public static void main(String[] args) {
int x = 0;
if(false & (++x > 0)) { }
System.out.println(x);

int y = 0;
if(false && (++y > 0)) { }
System.out.println(y);
}
}

Output:

1
0

Explanation: & evaluates both sides, && short-circuits.


2️⃣7️⃣ Generic Type Erasure

import java.util.*;

public class Test {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass() == list2.getClass());
}
}

Output:

true

Explanation: Generic types are erased at runtime; both are ArrayList.


2️⃣8️⃣ Varargs Ambiguity

public class Test {
static void test(int... nums) { System.out.println("int"); }
static void test(Integer... nums) { System.out.println("Integer"); }

public static void main(String[] args) {
test(1, 2, 3);
}
}

Output:

Compilation Error: ambiguous method call

Explanation: Compiler cannot decide between primitive and wrapper varargs.


2️⃣9️⃣ Interface Variable Hiding

interface A {
int X = 10;
}

interface B {
int X = 20;
}

class C implements A, B {
public static void main(String[] args) {
System.out.println(X);
}
}

Output:

Compilation Error: reference to X is ambiguous

Explanation: Both interfaces define X; must use A.X or B.X to resolve.


3️⃣0️⃣ Finally Block Return

public class Test {
static int test() {
try {
return 1;
} finally {
return 2;
}
}

public static void main(String[] args) {
System.out.println(test());
}
}

Output:

2

Explanation: Finally block return overrides try block return.


3️⃣1️⃣ Anonymous Inner Class

public class Test {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
System.out.println("Running");
}
};
r.run();
}
}

Output:

Running

Explanation: Anonymous inner class implements interface on-the-fly.


3️⃣2️⃣ Enum with Constructor

enum Day {
MON("Monday"), TUE("Tuesday");

String fullName;
Day(String name) { this.fullName = name; }
}

public class Test {
public static void main(String[] args) {
System.out.println(Day.MON.fullName);
}
}

Output:

Monday

Explanation: Enums can have constructors and fields.


3️⃣3️⃣ BitWise NOT

public class Test {
public static void main(String[] args) {
System.out.println(~5);
}
}

Output:

-6

Explanation: Bitwise NOT inverts all bits; ~5 = -6 (two's complement).


3️⃣4️⃣ HashCode & Equals

import java.util.*;

class Person {
String name;
Person(String n) { name = n; }
}

public class Test {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
Person p1 = new Person("John");
set.add(p1);
set.add(new Person("John"));
System.out.println(set.size());
}
}

Output:

2

Explanation: Without overriding equals/hashCode, each Person is treated as unique.


3️⃣5️⃣ Primitive Widening

public class Test {
static void test(long l) { System.out.println("long"); }

public static void main(String[] args) {
int x = 10;
test(x);
}
}

Output:

long

Explanation: int is automatically widened to long.


🔴 Advanced Level (36-50)

3️⃣6️⃣ Weak Reference & GC

import java.lang.ref.*;

public class Test {
public static void main(String[] args) {
String s = new String("Hello");
WeakReference<String> wr = new WeakReference<>(s);
s = null;
System.gc();
System.out.println(wr.get());
}
}

Output:

null (usually, non-deterministic)

Explanation: WeakReference allows GC to collect object if no strong references exist.


3️⃣7️⃣ Thread Join

public class Test {
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> System.out.print("A"));
t.start();
t.join();
System.out.print("B");
}
}

Output:

AB

Explanation: join() waits for thread to complete before continuing.


3️⃣8️⃣ Transient Variable

import java.io.*;

class Person implements Serializable {
String name;
transient int age;

Person(String n, int a) { name = n; age = a; }
}

public class Test {
public static void main(String[] args) throws Exception {
Person p = new Person("John", 30);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(p);

ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray()));
Person p2 = (Person) ois.readObject();

System.out.println(p2.name + " " + p2.age);
}
}

Output:

John 0

Explanation: transient fields are not serialized; age defaults to 0.


3️⃣9️⃣ Lambda Capture

import java.util.function.*;

public class Test {
public static void main(String[] args) {
int x = 10;
Supplier<Integer> s = () -> x;
// x = 20; // Would cause compilation error
System.out.println(s.get());
}
}

Output:

10

Explanation: Lambdas can only capture effectively final variables.


4️⃣0️⃣ Method Reference

import java.util.*;

public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(System.out::println);
}
}

Output:

a
b
c

Explanation: :: is method reference syntax for functional interfaces.


4️⃣1️⃣ Stream Terminal Operation

import java.util.stream.*;

public class Test {
public static void main(String[] args) {
Stream<Integer> s = Stream.of(1, 2, 3);
s.forEach(System.out::print);
s.forEach(System.out::print);
}
}

Output:

IllegalStateException: stream has already been operated upon

Explanation: Streams can only be consumed once.


4️⃣2️⃣ Optional.orElse vs orElseGet

import java.util.*;

public class Test {
static String expensive() {
System.out.print("Called-");
return "Default";
}

public static void main(String[] args) {
Optional<String> opt = Optional.of("Value");
System.out.println(opt.orElse(expensive()));
}
}

Output:

Called-Value

Explanation: orElse() evaluates argument even if Optional has value; use orElseGet() for lazy evaluation.


4️⃣3️⃣ CompletableFuture

import java.util.concurrent.*;

public class Test {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenAccept(System.out::println)
.join();
}
}

Output:

Hello World

Explanation: CompletableFuture chains asynchronous operations.


4️⃣4️⃣ Volatile Variable

class Test {
static volatile boolean flag = false;

public static void main(String[] args) throws Exception {
new Thread(() -> {
while(!flag) { }
System.out.println("Done");
}).start();

Thread.sleep(100);
flag = true;
}
}

Output:

Done

Explanation: volatile ensures visibility of changes across threads.


4️⃣5️⃣ ClassLoader Hierarchy

public class Test {
public static void main(String[] args) {
System.out.println(Test.class.getClassLoader());
System.out.println(String.class.getClassLoader());
}
}

Output:

jdk.internal.loader.ClassLoaders$AppClassLoader@...
null

Explanation: Bootstrap classloader (loads core Java classes) is represented as null.


4️⃣6️⃣ Reflection Private Access

import java.lang.reflect.*;

class Secret {
private String data = "Hidden";
}

public class Test {
public static void main(String[] args) throws Exception {
Secret s = new Secret();
Field f = Secret.class.getDeclaredField("data");
f.setAccessible(true);
System.out.println(f.get(s));
}
}

Output:

Hidden

Explanation: Reflection can access private fields with setAccessible(true).


4️⃣7️⃣ Phantom Reference

import java.lang.ref.*;

public class Test {
public static void main(String[] args) {
Object obj = new Object();
ReferenceQueue<Object> rq = new ReferenceQueue<>();
PhantomReference<Object> pr = new PhantomReference<>(obj, rq);

System.out.println(pr.get());
obj = null;
}
}

Output:

null

Explanation: PhantomReference.get() always returns null; used for pre-GC cleanup.


4️⃣8️⃣ Annotation Processing

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String value();
}

@MyAnnotation("Test")
class Test {
public static void main(String[] args) {
MyAnnotation ann = Test.class.getAnnotation(MyAnnotation.class);
System.out.println(ann.value());
}
}

Output:

Test

Explanation: Runtime annotations can be accessed via reflection.


4️⃣9️⃣ ForkJoinPool

import java.util.concurrent.*;

class Task extends RecursiveTask<Integer> {
int n;
Task(int n) { this.n = n; }

protected Integer compute() {
if(n <= 1) return n;
Task t1 = new Task(n-1);
t1.fork();
Task t2 = new Task(n-2);
return t2.compute() + t1.join();
}
}

public class Test {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
System.out.println(pool.invoke(new Task(5)));
}
}

Output:

5

Explanation: ForkJoinPool computes Fibonacci(5) = 5 using work-stealing algorithm.


5️⃣0️⃣ Module System (Java 9+)

// module-info.java
module mymodule {
exports com.example;
}

// Main.java
package com.example;

public class Test {
public static void main(String[] args) {
System.out.println("Module: " + Test.class.getModule().getName());
}
}

Output:

Module: mymodule

Explanation: Java 9+ module system encapsulates packages and controls access.


📚 Summary

These 50 problems cover:

  • String & Object Management: Pool, immutability, comparison
  • Auto-boxing & Caching: Integer, Boolean caching ranges
  • Operators: Pre/post increment, short-circuit, bitwise
  • OOP Concepts: Inheritance, polymorphism, overloading/overriding
  • Collections: List operations, HashMap, generics, type erasure
  • Concurrency: Threads, volatile, synchronization, CompletableFuture
  • Advanced Java: Lambdas, streams, reflection, serialization, modules

Pro Tip: Always test your assumptions in Java! Many "obvious" behaviors have subtle gotchas. 🎯