Text blocks — what changed in Java 15
EasyJava 15 made text blocks standard: a multi-line string between """ delimiters. The compiler strips the shared indentation and trailing spaces and turns line endings into \n. No escaped quotes or + chains. The result is an ordinary String.
How it works
- Syntax. Opening
"""must be followed by a line break; content starts on the next line. The closing"""can sit at the end of the last line or on its own line. - History. Preview in Java 13 and 14, standard (final) in Java 15 (JEP 378).
- What the compiler does, in order:
- Normalizes every line ending (
\r\n,\r) to\n, so the value doesn't depend on the OS that saved the file. - Removes incidental indentation: the smallest leading whitespace among the non-blank lines (and the closing delimiter's line) is stripped from every line.
- Strips trailing spaces from each line.
- Only then interprets escape sequences.
- Normalizes every line ending (
- New escapes.
\at the end of a line joins it with the next (no\n).\sis a single space that survives the trailing-space strip. - Same type. The result is a compile-time constant
String, interned like any literal. Java 15 also addedString.formatted(...), handy for filling in values.
Example
// Before: escapes and concatenation
String oldJson = "{\n" +
" \"sku\": \"%s\",\n" +
" \"qty\": %d\n" +
"}\n";
// After: what you see is what you get
String json = """
{
"sku": "%s",
"qty": %d
}
""".formatted("KB-104", 3);
// Line-join and a kept trailing space
String sql = """
SELECT id, name \
FROM customers \
WHERE active = true"""; // one line, no trailing \n
String padded = """
name:\s
"""; // "name: \n"Edge cases
- The closing delimiter's position controls indentation. Move it left of the content and the extra spaces become part of the string.
- Closing
"""on its own line adds a final\n; closing on the last content line doesn't. - A single
"or a pair""needs no escaping inside. Three in a row do: write\""". - Mixing tabs and spaces in indentation is legal but confusing, since each counts as one whitespace character.
Common mistakes
- Putting content on the same line as the opening
""". That's a compile error. - Expecting text blocks to interpolate variables like
${name}. Java has no string interpolation; useformattedor+. - Being surprised by a trailing
\nin tests that compare against a literal without one.
Likely follow-up
"Are text blocks slower or different at runtime?" No. All processing happens at compile time. The bytecode holds an ordinary string constant, the same as a regular literal with the escapes written out.
Get every deep dive in the app
Coming soon to the App StoreComing soon to Google Play