HuntExams Academy logo
JavaBeginner#puzzle#strings

What is the output of this code? String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System.out.println(s1 == s2); System.out.println(s1 == s3);

Answer

s1 and s2 both refer to the same interned literal in the String pool, so s1 == s2 is true. s3 is a new heap object, so s1 == s3 compares different references and is false.

Example

String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false

Detailed explanation

The code prints true on the first line and false on the second line. The important distinction is between reference identity and string content. In Java, when == is applied to object references, it checks whether both operands refer to the same object. It does not compare the characters stored in those objects. Therefore, two String variables can represent identical text while an == comparison between them returns false.

The assignment String s1 = "abc" uses a string literal. Java interns string literals, meaning that equal literals share a canonical String instance maintained through the String pool. When String s2 = "abc" executes, s2 receives a reference to that same canonical instance rather than a separate object containing the same characters. Consequently, s1 == s2 evaluates to true. The pool is not a separate category of object outside the heap: in modern Java implementations, pooled strings are also heap objects. What matters here is their shared identity, not a supposed heap-versus-pool distinction.

The expression new String("abc") explicitly creates a distinct String object and assigns its reference to s3. Its content is still abc, but its identity differs from the literal referenced by s1 and s2. Thus, s1 == s3 evaluates to false. The constructor does not necessarily create a separate copy of the underlying character storage; the guaranteed distinction relevant to this question is the newly created String object. If the code instead printed s1.equals(s3), the result would be true because String.equals compares character content.

Interviewers use this question to test whether you can separate objects, references, and values rather than merely recall the output. Explain the shared literal first, then the explicit allocation, and finally the operator being used. You can also mention that s3.intern() returns the canonical pooled reference, so s1 == s3.intern() would be true. Calling intern() does not change s3 itself; you must use or assign the returned reference.

Key points to remember

  • The output is true, followed by false on the next line.
  • For object references, == compares identity rather than content.
  • s1 and s2 reference the same interned String literal.
  • new String("abc") creates a distinct String object referenced by s3.
  • s1.equals(s3) returns true because both strings contain the same characters.

Common mistakes candidates make

  • Saying == compares the characters in two String objects.
  • Claiming pooled strings are outside the heap while only newly constructed strings are on the heap.
  • Assuming s3.intern() changes s3 to reference the pooled object without assigning the result.

Likely follow-up questions

What would s2.equals(s3) print?

It would print true. String.equals compares character content, and both objects contain abc.

What happens after s3 = s3.intern()?

s3 is reassigned to the canonical pooled String instance for abc. After that assignment, s1 == s3 evaluates to true.

Would String s4 = "a" + "bc" make s1 == s4 true?

Yes, because this concatenation is a compile-time constant expression whose result is interned. Concatenation involving runtime values is not automatically guaranteed to return that pooled instance.

Interview tip: State both output lines immediately, then explain shared literal identity versus explicit object creation and contrast == with equals().

Related Interview Questions

1
JavaAdvanced#puzzle#exceptions

What does this code output and why? try { return 1; } finally { return 2; }

Open
2
JavaAdvanced#puzzle#collections

What is the output? List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); for (Integer i : list) { if (i == 1) list.remove(i); }

Open
3
JavaIntermediate#puzzle#oop

What is the output of this code involving static and instance initialization order? class A { static { System.out.println("static A"); } { System.out.println("instance A"); } A() { System.out.println("constructor A"); } } new A(); new A();

Open