DEV Community

realNameHidden
realNameHidden

Posted on

What Happens Internally When You Write String s = new String("Hello"); in Java?

Discover what happens behind the scenes in Java when you write String s = new String("Hello");. Learn about memory, String Pool, and best practices.


🧩 Introduction

Imagine you’re baking a cake. You can either use an existing recipe or create a brand-new one. In Java, something similar happens when you create a String.

Most beginners learn early that String is a special class in Java — but few truly understand what goes on under the hood when you write something as simple as:

String s = new String("Hello");
Enter fullscreen mode Exit fullscreen mode

It looks harmless, but internally, a fascinating series of events happens involving memory management, the String Pool, and object creation.

Understanding this concept is essential for every Java developer who wants to write efficient, optimized, and bug-free code. Let’s explore what’s happening behind the scenes — in plain, beginner-friendly language.


⚙️ Core Concepts — What Really Happens Behind the Scenes

When you write:

String s = new String("Hello");
Enter fullscreen mode Exit fullscreen mode

you’re actually doing two things at once. Let’s break it down step by step.

1️⃣ Step 1 — "Hello" goes into the String Pool

Java maintains a special area in the heap memory called the String Constant Pool (SCP).

When the JVM sees "Hello", it checks the pool to see if "Hello" already exists.

  • If it does not, it creates a new String object in the pool.
  • If it does, it reuses the existing one.

This behavior is what makes String objects memory-efficient and immutable.

So after this step, the pool contains "Hello".

2️⃣ Step 2 — new String("Hello") creates a new object in the heap

The new keyword always forces the creation of a new object in the heap memory, even if the same value already exists in the String Pool.

So now, we have:

  • One "Hello" object in the String Pool.
  • One new "Hello" object in the Heap (created using new).

Both contain the same text, but they are two separate objects.

This means:

String s1 = "Hello";
String s2 = new String("Hello");

System.out.println(s1 == s2); // false (different memory locations)
Enter fullscreen mode Exit fullscreen mode

Even though both hold the same text value, s1 and s2 are not the same object.

3️⃣ Step 3 — Reference assignment

The variable s now references the newly created heap object.
The pool version still exists, but it’s not directly referenced by s.

This is why String s = new String("Hello"); is often considered redundant — you’re creating two copies of the same String unnecessarily.


💻 Code Examples

Example 1 — Comparing String Literals vs. new String()

public class StringExample1 {
    public static void main(String[] args) {
        // String literal - created in String Pool
        String s1 = "Hello";

        // new String() - creates a new object in Heap
        String s2 = new String("Hello");

        // Comparing references
        System.out.println(s1 == s2);  // false → different memory locations

        // Comparing actual content
        System.out.println(s1.equals(s2));  // true → same text value
    }
}
Enter fullscreen mode Exit fullscreen mode

🧠 Explanation:

  • == checks if both references point to the same object.
  • .equals() checks if both strings have the same content.

Example 2 — Using intern() to Reuse String Pool Objects

public class StringExample2 {
    public static void main(String[] args) {
        String s1 = new String("Java");
        String s2 = s1.intern(); // forces reuse of the String Pool

        String s3 = "Java";

        // s2 and s3 now point to the same object in the pool
        System.out.println(s2 == s3);  // true
    }
}
Enter fullscreen mode Exit fullscreen mode

🧠 Explanation:
Calling .intern() tells the JVM to return the reference from the String Pool instead of creating a new one.
This is how you can ensure all identical strings share the same memory space, improving efficiency.


✅ Best Practices for Working with Strings in Java

Here are some practical tips and common pitfalls to keep in mind:

  1. Avoid using new String() unless absolutely necessary.
    Creating strings with new bypasses the String Pool and wastes memory.

  2. Use string literals (String s = "Hello";) whenever possible.
    They are faster and more memory-efficient because of pooling.

  3. Use .equals() for content comparison, not ==.
    The == operator only checks memory addresses.

  4. Intern only when needed.
    intern() helps reuse strings, but overusing it may lead to higher memory usage due to the pool’s fixed size.

  5. Remember: Strings are immutable.
    Any modification (like s.concat("World")) creates a new String.
    For heavy string manipulation, prefer StringBuilder or StringBuffer.


🏁 Conclusion

To sum it up: when you write

String s = new String("Hello");
Enter fullscreen mode Exit fullscreen mode

Java first places "Hello" in the String Pool (if it isn’t already there), then creates a brand-new String object in the heap.

This simple line involves two memory areas, two object creations (potentially), and one reference assignment.

While it’s a great exercise to understand how the JVM works internally, in real-world coding, prefer using string literals — they’re cleaner, faster, and memory-efficient.

So next time you see a line like this, you’ll know exactly what magic the JVM performs behind the scenes! ✨


Top comments (0)