Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Comparison Questions - Part 2
JAVA

Comparison Questions - Part 2

Practice 15 Java comparison questions covering wrapper objects, null, the String pool, objects, and StringBuilder.

16. .equals() on out-of-cache Integers

Integer a = 200;
Integer b = 200;

System.out.println(a.equals(b));

Output: true

== fails for two out-of-cache boxed Integers (question 15), but .equals() compares the wrapped values, which are both 200 — so it is true. Always use .equals() for wrapper comparison.

17. Integer == int unboxing ⭐⭐⭐⭐⭐

Integer a = 100;
int b = 100;

System.out.println(a == b);

Output: true

When one operand is a primitive int, the Integer is unboxed and == compares values: 100 == 100true. The unboxing rule overrides the reference-comparison behavior you’d get between two Integer objects.

18. Double wrapper comparison

Double a = 10.5;
Double b = 10.5;

System.out.println(a == b);
System.out.println(a.equals(b));

Output:

false
true

Double has no guaranteed cache like Integer’s -128..127 range, so the two autoboxed objects are distinct — == is false. .equals() compares the double values → true.

19. == on two separately created objects ⭐⭐⭐⭐⭐

class Student {
    int age;

    Student(int age) {
        this.age = age;
    }
}

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student(20);
        Student s2 = new Student(20);

        System.out.println(s1 == s2);
    }
}

Output: false

Each new allocates a separate object. == compares references, and the two references point to different objects — even though the age fields are equal. Without an overridden equals(), object identity is all == sees.

20. == on the same object reference

Student s1 = new Student(20);
Student s2 = s1;

System.out.println(s1 == s2);

Output: true

Student s2 = s1 copies the reference, not the object. Both variables point to the same object, so == is true. This is the counterpart to question 19.

21. == against null

String s = null;

System.out.println(s == null);

Output: true

s contains the null reference. s == null is true — comparing any reference variable to null tests whether it is null.

22. == between two null references

String a = null;
String b = null;

System.out.println(a == b);

Output: true

Both variables hold the same null reference, so a == b is true. There is only one null — every null reference is identical.

23. Calling .equals() on a null reference

String a = null;

System.out.println(a.equals("Java"));

Output: NullPointerException

You cannot call an instance method on null. a.equals(...) dereferences a, which is null, and throws NullPointerException before any comparison happens.

24. Safe null comparison with .equals() ⭐⭐⭐⭐⭐

String a = null;

System.out.println("Java".equals(a));

Output: false

Calling equals() on the literal is safe — the receiver is a valid object. It compares "Java" against null and returns false (no exception). This is the recommended pattern for null-safe comparison.

25. Compile-time constant concatenation and ==

String a = "Java";
String b = "Ja" + "va";

System.out.println(a == b);

Output: true

"Ja" + "va" is a compile-time constant, folded to "Java" by the compiler. It resolves to the same string-pool object as a, so == is true. Constant folding keeps both references in the pool.

26. Runtime String concatenation ⭐⭐⭐⭐⭐

String a = "Java";

String b = "Ja";
String c = b + "va";

System.out.println(a == c);
System.out.println(a.equals(c));

Output:

false
true

b + "va" is a runtime concatenation, which creates a new String object — it is not pooled. So a == c is false. The content is still "Java", so .equals() is true. Whether concatenation is compile-time or runtime decides pool membership.

27. StringBuilder comparison ⭐⭐⭐⭐⭐

StringBuilder a = new StringBuilder("Java");
StringBuilder b = new StringBuilder("Java");

System.out.println(a == b);
System.out.println(a.equals(b));

Output:

false
false

a and b are distinct objects → == is false. Crucially, StringBuilder does not override equals() for content, so a.equals(b) falls back to Object.equals() — reference identity — and is also false. To compare contents you must call .toString().equals(...).

28. == on two separate subclass instances

class Animal {}

class Dog extends Animal {}

public class Test {
    public static void main(String[] args) {
        Animal a = new Dog();
        Animal b = new Dog();

        System.out.println(a == b);
    }
}

Output: false

Both references have type Animal, but each new Dog() creates a separate object. Inheritance does not change reference comparison — == still checks identity, so the result is false.

29. Boolean comparison

boolean a = true;
boolean b = false;

System.out.println(a == b);
System.out.println(a != b);

Output:

false
true

boolean is a primitive; == compares values. true == false is false, and true != false is true.

30. The classic mixed comparison ⭐⭐⭐⭐⭐

public class Test {
    public static void main(String[] args) {

        String s1 = "Java";
        String s2 = "Java";
        String s3 = new String("Java");

        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;

        System.out.println(s1 == s2);
        System.out.println(s1 == s3);
        System.out.println(s1.equals(s3));

        System.out.println(i1 == i2);
        System.out.println(i3 == i4);
        System.out.println(i3.equals(i4));
    }
}

Output:

true
false
true
true
false
true

Everything above in one place: s1 == s2 pooled literals → true; s1 == s3 distinct new object → false; .equals() content → true. For the wrappers, i1/i2 share the cached 100 object → true; i3/i4 at 200 are outside the cache → false for ==, true for .equals(). Memorize this output set and you have the whole comparison chapter covered.

My Private Notes

Notes are auto-saved locally to this device.