Strings — String Pool, Immutability, StringBuilder, StringBuffer, and Text Blocks
In this tutorial, you will learn about Strings. We cover key concepts, practical examples, and best practices to help you master this topic.
Java strings are immutable sequences of characters stored in a special memory area called the string pool. Unlike C where strings are mutable character arrays, Java's String class is designed for safety and performance — once created, a string's content never changes, which enables the string pool, Caching of hash codes, and secure handling of sensitive data.
What You'll Learn
- How the string pool works and why strings are immutable
StringBuildervsStringBufferfor mutable strings- Text blocks for multi-line strings (Java 13+)
- Common string methods and their behavior
Why It Matters
String misuse is one of the most common performance problems in Java. Concatenating strings in a loop creates garbage objects. Using StringBuilder properly can be 100x faster. Understanding immutability also explains why String is thread-safe by default.
Real-World Use
Logging frameworks, template engines, SQL query builders, XML/JSON parsers, and web frameworks all Process strings intensively. Every HTTP request and response is string-based.
String Immutability
A String object cannot be changed after creation:
String s = "Hello";
s.toUpperCase(); // returns a NEW string "HELLO", original unchanged
System.out.println(s); // "Hello"
All methods that appear to modify a string (toUpperCase(), trim(), substring(), replace()) return new String objects.
Why Immutable?
- String Pooling — The JVM can safely share string literals
- Security — Network connections, file paths, and class names are strings; immutability prevents tampering
- Hash Code Caching — The hash code is computed once and cached (since the value never changes)
- Thread Safety — Immutable objects are inherently thread-safe
The String Pool
The string pool is a special memory region (in the heap, not the stack) where the JVM caches string literals:
String a = "Hello";
String b = "Hello";
String c = new String("Hello");
System.out.println(a == b); // true (same reference from pool)
System.out.println(a == c); // false (c is a new object on the heap)
System.out.println(a.equals(c)); // true (same characters)
When you write "Hello", the JVM checks the pool. If the string exists, it returns the pooled reference. If not, it creates a new string in the pool.
The new String("Hello") constructor bypasses the pool — it always creates a new object. You can manually intern a string:
String d = c.intern();
System.out.println(a == d); // true (now from the pool)
Common String Methods
String s = " Hello, World! ";
s.length(); // 17
s.charAt(0); // ' '
s.substring(2, 7); // "Hello"
s.indexOf("World"); // 8
s.contains("Hello"); // true
s.startsWith(" He"); // true
s.endsWith("! "); // true
s.toUpperCase(); // " HELLO, WORLD! "
s.toLowerCase(); // " hello, world! "
s.trim(); // "Hello, World!" (removes leading/trailing whitespace)
s.replace("World", "Java"); // " Hello, Java! "
s.split(", "); // [" Hello", "World! "]
s.isEmpty(); // false
s.isBlank(); // false (Java 11+)
Checking for Empty or Blank
String s1 = "";
String s2 = " ";
s1.isEmpty(); // true
s2.isEmpty(); // false
s2.isBlank(); // true (Java 11+)
String Concatenation
The + Operator
String s = "Hello" + " " + "World"; // "Hello World"
The compiler optimizes simple concatenation into StringBuilder calls. However, in a loop, this optimization degrades:
// BAD: creates a new StringBuilder each iteration
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // equivalent to: result = new StringBuilder(result).append(i).toString()
}
StringBuilder (Not Thread-Safe, Faster)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();
StringBuilder is the recommended choice for most use cases. It is mutable and avoids creating intermediate strings.
StringBuffer (Thread-Safe, Slower)
StringBuffer buffer = new StringBuffer();
buffer.append("Hello");
buffer.append(" ");
buffer.append("World");
String result = buffer.toString();
StringBuffer is synchronized — all methods are thread-safe. Use it only when multiple threads access the same buffer. In single-threaded code, StringBuilder is faster.
Text Blocks (Java 13+, Standardized in 15)
Text blocks provide a clean way to write multi-line strings without escaping newlines and quotes:
String json = """
{
"name": "Alice",
"age": 30,
"city": "New York"
}
""";
Key rules:
- Opening
"""must be followed by a newline - The closing
"""determines the indentation (leading whitespace is stripped) - Common indentation is stripped based on the position of the closing
"""
String html = """
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
""";
Without text blocks, this would require explicit \n and \":
String html = "<html>\n <body>\n <h1>Hello, World!</h1>\n </body>\n</html>";
Text blocks also support formatted strings with formatted():
String template = """
Hello, %s!
You are %d years old.
""".formatted("Alice", 30);
String Performance Comparison
// Slow: ~100,000 ns for 10,000 iterations
String result = "";
for (int i = 0; i < 10_000; i++) {
result += "x";
}
// Fast: ~1,000 ns for 10,000 iterations
StringBuilder sb = new StringBuilder(10_000);
for (int i = 0; i < 10_000; i++) {
sb.append("x");
}
String result = sb.toString();
Pre-sizing the StringBuilder avoids internal array resizing.
Common Mistakes
- Using
==instead of.equals()for string comparison. Always use.equals()for value comparison.==checks reference identity. - Concatenating strings in a loop with
+. Creates O(n^2) garbage. UseStringBuilderinstead. - Forgetting that strings are immutable.
s.replace("a", "b")does not modifys— it returns a new string. Assign the result back tos. - Using
StringBufferwhenStringBuildersuffices.StringBufferis synchronized and slower. UseStringBuilderunless you need thread safety. - Assuming
isEmpty()checks for whitespace.isEmpty()only returnstruefor length 0. UseisBlank()(Java 11+) to check for whitespace-only strings.
Practice Questions
1. Why is String immutable in Java?
For string pooling, security, hash code caching, and thread safety.
2. What is the difference between StringBuilder and StringBuffer?
StringBuilder is not synchronized (faster, single-threaded). StringBuffer is synchronized (slower, thread-safe).
3. What does str.intern() do?
It adds the string to the string pool (if not already present) and returns the pooled reference.
4. How do text blocks handle indentation?
The closing """ determines the common leading whitespace that is stripped from each line.
5. Why is result += str in a loop bad practice?
Each iteration creates a new StringBuilder, appends, calls toString(), and assigns — resulting in O(n^2) time and excessive garbage.
Challenge Question:
Write a method String reverseWords(String sentence) that reverses the order of words but keeps each word's characters in the original order. Use StringBuilder for efficiency. Example: "Hello World Java" becomes "Java World Hello".
FAQ
{{< faq "How many objects are created by String s = new String(\"Hello\")?" "Possibly two. The literal \"Hello\" is placed in the string pool (one object). The new keyword creates a second object on the heap. Avoid this constructor unless you explicitly need a separate copy." >}}
Mini Project
Write a program StringPlayground.java that:
- Creates a long string by concatenating numbers 1 to 1000 in a loop using
+(measure time withSystem.nanoTime()) - Repeats the same with
StringBuilderand compares the time - Uses a text block to define a multi-line JSON string representing a person object
- Parses the text block manually to extract the name and age values (without using a JSON library)
- Demonstrates string pooling: create 5 strings with literal values, 5 with
new String(), and compare them with==and.equals() - Reverses a sentence word-by-word using
StringBuilder
Print each section with clear labels so the output is self-documenting.
What's Next
You have mastered the fundamentals of Java syntax, data types, control flow, loops, arrays, methods, and strings. Now it is time to enter the world of object-oriented programming. Lesson 11 introduces classes and objects — constructors, the this keyword, instance vs static members, and initialization blocks.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro