Text Blocks
Introduction
Text blocks, introduced as a preview feature in Java 13 and standardized in Java 15, revolutionize how developers work with multi-line strings in Java. They provide a clean, readable way to write strings that span multiple lines without the need for concatenation, escape sequences, or manual formatting-making code more maintainable and dramatically improving readability.
Text blocks are particularly valuable for:
- HTML/XML content
- JSON/YAML data
- SQL queries
- Multi-line documentation
- Code snippets and templates
The Problem with Traditional Strings
Before text blocks, writing multi-line strings in Java was difficult, messy, and prone to mistakes due to constant concatenation and escape characters.
Example 1: HTML Content
// Traditional approach - Ugly and hard to maintain
String html = "<html>\n" +
" <body>\n" +
" <h1>Welcome</h1>\n" +
" <p>Hello, World!</p>\n" +
" </body>\n" +
"</html>";Problems:
- ❌ Lots of
+concatenation operators - ❌ Explicit
\nescape sequences everywhere - ❌ Hard to visualize the actual output
- ❌ Easy to make mistakes with quotes and escapes
- ❌ Difficult to maintain and modify
- ❌ Poor readability
Example 2: JSON Data
// Traditional approach - Messy and error-prone
String json = "{\n" +
" \"name\": \"John Doe\",\n" +
" \"age\": 30,\n" +
" \"address\": {\n" +
" \"street\": \"123 Main St\",\n" +
" \"city\": \"New York\"\n" +
" }\n" +
"}";Problems:
- ❌ Every quote needs to be escaped:
\" - ❌ Manual newline insertion:
\n - ❌ Tedious concatenation with
+ - ❌ Hard to spot syntax errors
Example 3: SQL Query
// Traditional approach - Unreadable
String sql = "SELECT users.id, users.name, orders.total\n" +
"FROM users\n" +
"INNER JOIN orders ON users.id = orders.user_id\n" +
"WHERE orders.status = 'completed'\n" +
"ORDER BY orders.total DESC\n" +
"LIMIT 10";Problems:
- ❌ SQL query structure is obscured
- ❌ Difficult to align and format
- ❌ Maintenance nightmare when queries change
Text Blocks
Text blocks solve these problems with a clean, natural syntax using triple quotes (""").
Basic Syntax
String textBlock = """
Content goes here
Multiple lines are natural
No escaping needed (usually)
""";Key Components:
- Opening delimiter:
"""followed by a line terminator (newline) - Content: The actual text, spanning multiple lines
- Closing delimiter:
"""on its own line or at the end of content
Example 1: HTML with Text Blocks
// With text blocks - Clean and readable!
String html = """
<html>
<body>
<h1>Welcome</h1>
<p>Hello, World!</p>
</body>
</html>
""";Benefits:
- ✅ Natural formatting
- ✅ No concatenation needed
- ✅ No escape sequences
- ✅ Visually matches output
- ✅ Easy to maintain
Example 2: JSON with Text Blocks
// With text blocks - Beautiful!
String json = """
{
"name": "John Doe",
"age": 30,
"address": {
"street": "123 Main St",
"city": "New York"
}
}
""";Benefits:
- ✅ No quote escaping needed (double quotes work naturally)
- ✅ No
\nneeded - ✅ Proper indentation preserved
- ✅ Easy to validate and edit
Example 3: SQL with Text Blocks
// With text blocks - Crystal clear!
String sql = """
SELECT users.id, users.name, orders.total
FROM users
INNER JOIN orders ON users.id = orders.user_id
WHERE orders.status = 'completed'
ORDER BY orders.total DESC
LIMIT 10
""";Benefits:
- ✅ SQL query is immediately readable
- ✅ Proper formatting maintained
- ✅ Easy to modify and debug
Text Block Rules and Behavior
1. Opening Delimiter Requirements
The opening """ must be followed by a line terminator:
// WRONG: No line terminator after opening delimiter
String text = """Hello World""";
// CORRECT: Line terminator after opening delimiter
String text = """
Hello World
""";
// ALSO CORRECT: Closing delimiter on same line as content
String text = """
Hello World""";2. Indentation Handling (Incidental Whitespace)
Text blocks automatically strip incidental indentation, the common leading whitespace from all lines.
public class Example {
public static void main(String[] args) {
String text = """
Line 1
Line 2
Line 3 (extra indent)
""";
System.out.println(text);
}
}
// Output:
// Line 1
// Line 2
// Line 3 (extra indent)How it works:
- The compiler finds the line with the least indentation (excluding empty lines)
- That indentation level is stripped from all lines
- The closing
"""position determines the baseline indentation
Example with closing delimiter:
// Closing delimiter at column 10
String text = """
Hello
World
"""; // This line determines indentation
// Closing delimiter at column 0
String text = """
Hello
World
"""; // Different indentation!3. Escape Sequences
Most escape sequences work normally, but some have special handling:
// Regular escape sequences work
String text = """
Line 1\tTab here
Line 2\nExtra newline follows
""";
// Special: Escape newline to join lines
String text = """
This is a \
single line
""";
// Output: "This is a single line"
// Special: Escape space to preserve trailing whitespace
String text = """
Line with trailing space\s
""";Common Escape Sequences:
\n- Newline (usually not needed)\t- Tab\"- Double quote (usually not needed in text blocks)\\- Backslash\s- Space (preserves trailing whitespace)\(at line end) - Escape newline (line continuation)
4. Quote Handling
Double quotes (") don't need escaping in text blocks:
String text = """
She said, "Hello!"
JSON: {"key": "value"}
""";
// No escaping needed!Exception: Three consecutive double quotes need escaping:
// WRONG: Closes text block early
String text = """
Code: String s = """;
""";
// CORRECT: Escape one quote
String text = """
Code: String s = \""";
""";
// OR: Use different formatting
String text = """
Code: String s = "" ";
""";5. Line Terminators
Text blocks preserve line terminators as \n, regardless of the platform:
String text = """
Line 1
Line 2
""";
// On Windows: Still uses \n (not \r\n)
// On Unix/Mac: Uses \n
// Consistent across all platforms!Practical Examples
Example: JSON API Response
public class ApiResponse {
public static String createUserResponse(String id, String name, String email, boolean active) {
return """
{
"status": "success",
"data": {
"id": "%s",
"name": "%s",
"email": "%s",
"active": %b,
"created_at": "2024-01-15T10:30:00Z"
}
}
""".formatted(id, name, email, active);
}
public static void main(String[] args) {
String response = createUserResponse("123", "John Doe", "john@example.com", true);
System.out.println(response);
}
}Example: Multi-line Log Messages
public class Logger {
public static void logError(String operation, String error, String stackTrace) {
String message = """
================== ERROR ==================
Operation: %s
Error: %s
Timestamp: %s
Stack Trace:
%s
===========================================
""".formatted(operation, error, java.time.Instant.now(), stackTrace);
System.err.println(message);
}
}String Methods with Text Blocks
1. formatted() Method
Returns a new formatted string by replacing format specifiers (like %s, %d) with the provided arguments.
String name = "Alice";
int age = 30;
String message = """
Name: %s
Age: %d
Status: Active
""".formatted(name, age);2. String.format()
Formats a string using placeholders and arguments, similar to printf, and returns the formatted result.
String formatted = String.format("""
{
"user": "%s",
"score": %d
}
""", "Bob", 95);3. replace(), replaceAll()
Replaces occurrences of specified text (replace) or regex patterns (replaceAll) with new values in a string.
String template = """
Hello, {{name}}!
Your balance is {{balance}}.
""";
String message = template
.replace("{{name}}", "Charlie")
.replace("{{balance}}", "$1,234.56");4. stripIndent(), translateEscapes()
stripIndent() removes common leading whitespace from each line, while translateEscapes() converts escape sequences (like \n, \t) into their actual characters.
// stripIndent() - manually strip incidental indentation
String text = " Line 1\n Line 2\n Line 3";
String stripped = text.stripIndent();
// translateEscapes() - process escape sequences
String raw = "Line 1\\nLine 2\\tTabbed";
String processed = raw.translateEscapes();5. split(), lines()
split() divides a string into an array based on a delimiter, while lines() returns a stream of individual lines separated by line terminators.
String text = """
Line 1
Line 2
Line 3
""";
// Get as array
String[] lines = text.split("\n");
// Get as Stream
text.lines().forEach(System.out::println);Advanced Techniques
1. Line Continuation
Use \ at the end of a line to continue on the next line without a newline:
String sentence = """
This is a very long sentence that spans \
multiple lines in the code but appears as \
a single line in the output.
""";
// Output: "This is a very long sentence that spans multiple lines in the code but appears as a single line in the output."2. Preserving Trailing Whitespace
Use \s to preserve trailing spaces:
String text = """
Line with trailing space\s
Another line\s\s
""";
// Without \s, trailing spaces would be stripped3. Empty Lines
Empty lines are preserved in text blocks:
String text = """
Paragraph 1
Paragraph 2
""";
// Output includes the blank line4. Mixing with Regular Strings
String header = "=".repeat(50);
String body = """
This is the main content.
It can span multiple lines.
""";
String footer = "=".repeat(50);
String document = header + "\n" + body + footer;String Templates (Java 21+ Preview)
String templates are a preview feature in Java 21 and may change.
String templates provide a more powerful way to interpolate values:
// Java 21+ String Templates (Preview)
String name = "Alice";
int age = 30;
String message = STR."""
Name: \{name}
Age: \{age}
Year of Birth: \{2024 - age}
""";
// More concise than formatted()Key differences:
- Uses
\{expression}syntax - Evaluates expressions inline
- More natural and readable
- Still in preview (syntax may change)
Summary
- Introduced in Java 15, text blocks simplify writing multi-line strings using
"""delimiters. - Improve readability by preserving natural formatting without concatenation or manual
\ncharacters. - Reduce escaping complexity, especially for quotes and structured content like JSON or HTML.
- Automatically manage indentation, producing cleaner and more maintainable code.
- Ideal for embedded content such as SQL queries, HTML/XML templates, JSON, and configuration data.
- Best Practice: Prefer text blocks whenever working with multi-line structured content to enhance clarity and maintainability.
Written By: Muskan Garg
How is this guide?
Last updated on
