Fundamentals 8 min read

Why Java Strings Are Final and How Interning Affects Memory

This article explains the two ways to create Java strings, demonstrates how string literals are shared in the method area, shows the effect of the intern() method at runtime, and discusses why the String class is final, immutable, and thread‑safe.

Programmer DD
Programmer DD
Programmer DD
Why Java Strings Are Final and How Interning Affects Memory

In Java there are two ways to create a string: using a literal (e.g., String x = "abc";) or using the constructor (e.g., String y = new String("abc");). The former stores the literal in the method area, while the latter creates a new object on the heap.

Example 1

String a = "abcd";
String b = "abcd";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True

The expression a == b is true because both a and b reference the same string literal in the method area. Java automatically interns compile‑time string literals, keeping only one copy (string pooling).

Example 2

String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d); // False
System.out.println(c.equals(d)); // True

Here c == d is false because each new String creates a distinct object on the heap, giving them different memory references.

Runtime String Interning

Strings can also be interned at runtime using the intern() method, which forces the string to be placed in the method‑area pool.

String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d); // Now true
System.out.println(c.equals(d)); // True

After interning, c == d becomes true because both references point to the same pooled literal.

Why the String Class Is Final

String Pool Requirement

The string intern pool resides in the method area. When a string is created, if an identical value already exists in the pool, the existing reference is returned instead of allocating a new object. This sharing would be unsafe for mutable strings.

Hashcode Caching

String’s hash code is cached (stored in a private int hash field) to avoid recomputation, which is important for collections like HashMap and HashSet. Immutability guarantees the hash code never changes.

Security

Many Java APIs (e.g., network connections, file handling) accept strings as parameters. If strings were mutable, a malicious change could alter a connection target or file path, leading to security vulnerabilities, including reflection attacks.

Thread‑Safety

Immutable objects can be freely shared across threads without synchronization, eliminating the need for explicit locking.

In summary, for efficiency, security, and thread‑safety reasons, String is designed as an immutable, final class.

Additional Notes

Understanding the difference between immutable objects and immutable references is important. For example: final User user = new User(); The user reference cannot be reassigned, but the User object itself may still be mutable.

Soul Questions

Both String and wrapper classes like Integer are final; why are they not recommended as synchronized lock objects?

Do you know what happens during autoboxing of primitive types?

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaMemory ManagementStringimmutabilityfinalinterning
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.