Java Text Block Syntax: Multiline Strings in Practice
java text block syntax: Learn Java text block syntax for multiline strings: delimiters, indentation stripping and escape sequences, plus formatting and migration guida...
Java text block syntax is straightforward: a multiline string literal is delimited by three double-quote characters. The opening """ must be followed by a line terminator; the closing """ may appear on its own line or immediately after the final content character.
The Core Syntax of a Text Block
A text block is declared with three double quotes at the start and three at the end. The content begins on the line after the opening delimiter, and the closing delimiter can stand alone or share the last content line.
String greeting = """ Hello, world! """;
In this example, greeting holds Hello, world! followed by a newline. The closing delimiter sits on its own line, which is the most common style because it makes the boundary of the text block explicit.
A text block can also close on the same line as the last content:
String greeting = """ Hello, world!""";
Here greeting holds Hello, world! with no trailing newline. The choice between the two forms depends on whether the trailing line terminator matters to the consumer of the string.
How Indentation Is Computed and Stripped
Text blocks strip incidental whitespace automatically. The compiler computes the minimum indentation across all content lines and the closing delimiter line, then removes that amount from every line. The closing delimiter's position therefore defines the left margin of the resulting string.
String sql = """ SELECT id, name FROM users WHERE active = true """;
The content lines and the closing delimiter are all indented eight spaces. The minimum indentation is eight, so each line is shifted left by eight spaces. The resulting string is:
SELECT id, name
FROM users
WHERE active = true
If the closing delimiter is indented less than the content lines, the excess indentation is preserved. For example, if the closing delimiter sits at four spaces while the content lines sit at eight, the minimum is four, and the content lines retain four spaces of leading whitespace. This behavior is often the source of surprising output when a text block is pasted into code with inconsistent indentation.
Tabs and spaces are counted as separate characters during indentation stripping. A tab is not expanded to a fixed number of spaces, so mixing tabs and spaces within a text block can produce inconsistent margins. Keeping the indentation uniform across all lines and the closing delimiter avoids this class of problem.
Escape Sequences and Line Continuations
Text blocks support the same escape sequences as ordinary string literals, plus two additional ones: \s and the line-continuation backslash.
The \s escape preserves a trailing space. Without it, trailing whitespace is removed from each line:
String aligned = """ name: Ada\s role: developer\s """;
The line-continuation backslash suppresses the line terminator at the end of a line. This is useful when you want to build a long logical line without embedding newlines:
String oneLine = """ first \ second \ third """;
The resulting string is first second third with no newline characters between the words. The spaces before the backslash are preserved, so the words are separated by single spaces.
Standard escapes such as \n, \t, and \" work inside text blocks. The sequence \" is rarely needed because a single double quote does not terminate a text block; only three consecutive quotes do.
Formatting Text Blocks with formatted()
Text blocks are ordinary String instances, so they support all String methods. The formatted() instance method is the most convenient way to inject values:
String report = """ Report for %s Total: %d """.formatted("Q3", 42);
The formatted() method behaves like String.format with the text block as the format string. Because text blocks preserve line structure, the format specifiers appear exactly where the output should place them.
A text block that contains format specifiers is no longer a compile-time constant. This affects usage in annotations or switch case labels, which require constant expressions. If constantness is required, the text block must avoid % sequences or be assigned through a non-constant path.
Common Syntax Mistakes and Their Causes
The most frequent mistake is omitting the required line terminator after the opening """. Writing """Hello""" on a single line is a syntax error; the opening delimiter must be followed by a line break.
Another common issue is assuming that the closing delimiter must be on its own line. It does not, but when it shares a line with content, the indentation stripping behaves differently because the closing delimiter's column becomes part of the calculation. This usually leads to unexpected leading spaces.
A third mistake is confusing the line-continuation backslash with the \n escape. The backslash joins lines; \n inserts a newline character. Using \n when you intended to continue a logical line produces embedded newlines that may break downstream parsing.
Compatibility and Migration Considerations
Text blocks are a standard feature since Java 15. Code compiled with a Java 15 or newer compiler can use them without flags. Codebases that must target Java 11 or earlier cannot use text blocks and must rely on string concatenation, String.join, or StringBuilder.
Migration from concatenated multiline strings is usually mechanical: replace the concatenation with a text block, then verify indentation. The main behavioral difference is trailing whitespace handling. Concatenation preserves exactly what you write, while text blocks strip incidental whitespace. Reviewing the output after migration catches most regressions.
For libraries that generate source code, SQL, or JSON, text blocks reduce escaping noise substantially. The tradeoff is that the indentation rules require attention when the generated content is embedded in a larger template. Keeping the closing delimiter at a consistent indentation relative to the surrounding code makes the stripping behavior predictable.