ReviseAlgo Logo

Common Java Pitfalls

String Comparison Mistakes

Understand the differences between reference identity and value equality, and how the JVM String Pool behaves.

Interview: A core junior-to-mid level interview filter. Expect questions on the String Pool, behavior of intern(), and safe null comparisons.

Last Updated: June 13, 2026 8 min read

In Java, Strings are objects, but their widespread use has led to special compiler optimizations, most notably the String Pool. This optimization often confuses developers about the difference between reference checks and value checks.

== Operator

Compares memory addresses (references). Returns true only if both variables point to the exact same memory location.

equals() Method

Compares the actual character sequences inside the String objects for semantic equality.

String Pool

A special storage area in the Java Heap where literals are cached to conserve system memory resources.

The String Pool Trap

When you write String s1 = "hello";, the JVM checks the String Pool. If "hello" is present, it returns the reference. If not, it creates it in the pool. Therefore, two literal-assigned strings point to the same address and s1 == s2 is true.

However, writing String s3 = new String("hello"); forces the creation of a new object on the heap, bypassing the pool checks. Now, s1 == s3 is false, even though their content is identical.

Code Walkthrough

This class demonstrates String references, literal pooling, and safe null checks.

public class StringPitfallsDemo {
    public static void main(String[] args) {
        String s1 = "java";
        String s2 = "java";
        String s3 = new String("java");

// Literal pooling optimization System.out.println(s1 == s2); // true (same address in String Pool) System.out.println(s1 == s3); // false (different heap memory addresses) System.out.println(s1.equals(s3)); // true (same character content)

// The intern() method manually returns pool reference String s4 = s3.intern(); System.out.println(s1 == s4); // true (intern returns the pooled instance)

// Dangers of NullPointerExceptions (NPE) String input = null; try { // Bad Practice: calling equals() on a variable that might be null boolean check = input.equals("admin"); } catch (NullPointerException e) { System.out.println("NPE caught! Avoid calling equals on variables."); }

// Good Practice 1: literal-first comparison boolean safeCheck1 = "admin".equals(input); // false, no NPE thrown

// Good Practice 2: Utility checks boolean safeCheck2 = java.util.Objects.equals(input, "admin"); // false, safe } }

Interview-Relevant Information

Q: How many objects are created by: String s = new String("hello")?
Answer: Up to two objects. First, the literal "hello" is checked. If it is not already in the String Pool, a String object is created in the pool. Second, the new String() constructor creates a brand new String object in the general heap area. If "hello" was already in the pool, only one new heap object is created.

Q: Can Strings be mutated? Why are they immutable?
Answer: No, Strings are immutable (cannot be changed after creation). Immutability is critical for security (passing db URLs, file paths safely), caching (ensuring hashCodes don't change, making String keys in HashMaps secure), and memory savings (enabling the String Pool).

Quick Checklist

Do you know when to use == vs equals()? Can you explain the purpose of String.intern()? If yes, you understand string pooling and comparison.

Use Cases

Securing credentials and database connection strings through immutable references.

Conserving heap space by pooling common application string tags.

Common Mistakes

Using == to compare string inputs received from external API layers or request payloads (always false).

Concatenating strings inside loops using the + operator instead of StringBuilder, creating massive heap allocation overhead.