A Java String is immutable — every operation that appears to modify one (concatenation, substring, replace) actually returns a new String object. String literals are automatically interned into a shared string pool, so two literals with identical content usually refer to the same object; strings created with new String(...) deliberately bypass the pool and always produce a distinct object. Because == compares object references, not content, using it to compare strings is a classic, genuinely common bug — .equals() is the correct way to compare string content.
== vs .equals(): the classic gotcha
s1 and s2 are both literals, so they're interned into the same pooled object — == happens to work here, which is exactly what makes the bug so easy to miss until s3 (created with new) breaks the pattern.
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true — both literals, same pooled object
System.out.println(s1 == s3); // false — s3 bypasses the pool, different object
System.out.println(s1.equals(s3)); // true — .equals() correctly compares CONTENTStringBuilder: mutable, for building strings in a loop
Because String is immutable, concatenating inside a loop with + creates a new String object on every single iteration — genuinely wasteful for large loops. StringBuilder mutates in place instead, and is the idiomatic tool for this exact case.
// avoid in a loop: creates a new String object every iteration
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // wasteful — allocates a new String each time
}
// idiomatic: StringBuilder mutates one buffer in place
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result2 = sb.toString();Text blocks: multi-line strings without escaping (Java 15+)
Triple-quote text blocks, finalized in Java 15, remove the need to escape quotes and manually concatenate lines for multi-line text like JSON or SQL — indentation is handled intelligently based on the closing delimiter's position.
String json = """
{
"name": "Alice",
"age": 30
}
""";
// no escaped quotes, no manual line concatenation needed