String Literal vs new String() in Java
Fast recall
Quick revision
Core answer
String s = "hello" uses the canonical interned literal. new String("hello") evaluates that literal and then creates a distinct String object with the same content; the new object is not automatically interned. Therefore equals() is true between them but == is false. The constructor is almost never needed for an existing String.Whether you understand the memory and identity implications of using a literal vs constructor, and can explain why == gives different results in each case.
Using == to compare a literal and a new String() and expecting true — they are different objects even if the content is identical.
Mention that `new String('hello')` is almost never the right choice in production code — the only reason you'd use it is if you have a very long char array and want a String from a small slice of it, preventing the whole array from being retained in memory.
Interview-ready guide
Interview answer
The literal form uses the canonical interned hello object. new String("hello") first evaluates that literal and then creates a separate String object with the same content. The new object is not automatically placed in the pool.
That gives literal.equals(created) == true but literal == created == false. In ordinary code the constructor adds no value because String is immutable, so I use the literal or existing String reference and compare text with equals().
String Literal vs new String() in Java
Direct Answer
String s = "hello" uses the canonical interned literal. new String("hello") evaluates that literal and then creates a distinct String object with the same content; the new object is not automatically interned. Therefore equals() is true between them but == is false. The constructor is almost never needed for an existing String.
Code Example
public class LiteralVsNew {
public static void main(String[] args) {
String s1 = "hello"; // goes to pool
String s2 = "hello"; // reuses pooled "hello"
String s3 = new String("hello"); // creates new heap object, skips pool
// Identity comparison (are they the same object?)
System.out.println(s1 == s2); // true — both point to pooled object
System.out.println(s1 == s3); // false — s3 is a different object
// Content comparison (do they have the same characters?)
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // true — same text, different object
// Lesson: always use .equals() for content comparison
// == is for checking if two variables point to the exact same object
}
}
Common Mistakes & Pitfalls
- Expecting
==to betruefor a literal and anew String— they hold the same characters but are different objects, so==isfalse; this is the single most commonStringbug for freshers. - Reaching for
new String("...")to 'make a copy' — it copies pointlessly; literals are already safe to share becauseStringis immutable, so the copy buys you nothing but wasted memory. - Assuming strings from input, files, or concatenation are pooled — only literals and explicitly
intern()-ed strings live in the pool; a value read at runtime is a fresh heap object, so==against a literal fails. - Thinking
.equals()and==are interchangeable —.equals()compares characters and is what you almost always want;==compares object identity and happens to work for literals by accident.
Check your understanding
Answer these without looking back at the article.
- What is the difference between == and .equals() for Strings in Java?
- Why does Java intern String literals automatically?
- What happens to a String created with new String() — does it ever get added to the pool?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.