JEP 378: Text Blocks
Summary
Add text blocks to the Java language. A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.
History
Text blocks were proposed by JEP 355 in early 2019 as a follow-on to explorations begun in JEP 326 (Raw String Literals), which was initially targeted to JDK 12 but eventually withdrawn and did not appear in that release. JEP 355 was targeted to JDK 13 in June 2019 as a preview feature. Feedback on JDK 13 suggested that text blocks should be previewed again in JDK 14, with the addition of two new escape sequences. Consequently, JEP 368 was targeted to JDK 14 in November 2019 as a preview feature. Feedback on JDK 14 suggested that text blocks were ready to become final and permanent in JDK 15 with no further changes.
Goals
-
Simplify the task of writing Java programs by making it easy to express strings that span several lines of source code, while avoiding escape sequences in common cases.
-
Enhance the readability of strings in Java programs that denote code written in non-Java languages.
-
Support migration from string literals by stipulating that any new construct can express the same set of strings as a string literal, interpret the same escape sequences, and be manipulated in the same ways as a string literal.
-
Add escape sequences for managing explicit white space and newline control.
Non-Goals
-
It is not a goal to define a new reference type, distinct from
java.lang.String
, for the strings expressed by any new construct. -
It is not a goal to define new operators, distinct from
+
, that takeString
operands. -
Text blocks do not directly support string interpolation. Interpolation may be considered in a future JEP. In the meantime, the new instance method
String::formatted
aids in situations where interpolation might be desired. -
Text blocks do not support raw strings, that is, strings whose characters are not processed in any way.
Motivation
In Java, embedding a snippet of HTML, XML, SQL, or JSON in a string literal "..."
usually requires significant editing with escapes and concatenation before the code containing the snippet will compile. The snippet is often difficult to read and arduous to maintain.
More generally, the need to denote short, medium, and long blocks of text in a Java program is near universal, whether the text is code from other programming languages, structured text representing golden files, or messages in natural languages. On the one hand, the Java language recognizes this need by allowing strings of unbounded size and content; on the other hand, it embodies a design default that strings should be small enough to denote on a single line of a source file (surrounded by " characters), and simple enough to escape easily. This design default is at odds with the large number of Java programs where strings are too long to fit comfortably on a single line.
Accordingly, it would improve both the readability and the writability of a broad class of Java programs to have a linguistic mechanism for denoting strings more literally than a string literal -- across multiple lines and without the visual clutter of escapes. In essence, a two-dimensional block of text, rather than a one-dimensional sequence of characters.
Still, it is impossible to predict the role of every string in Java programs. Just because a string spans multiple lines of source code does not mean that newline characters are desirable in the string. One part of a program may be more readable when strings are laid out over multiple lines, but the embedded newline characters may change the behavior of another part of the program. Accordingly, it would be helpful if the developer had precise control over where newlines appear, and, as a related matter, how much white space appears to the left and right of the "block" of text.
HTML example
Using "one-dimensional" string literals
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
Using a "two-dimensional" block of text
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
SQL example
Using "one-dimensional" string literals
String query = "SELECT \"EMP_ID\", \"LAST_NAME\" FROM \"EMPLOYEE_TB\"\n" +
"WHERE \"CITY\" = 'INDIANAPOLIS'\n" +
"ORDER BY \"EMP_ID\", \"LAST_NAME\";\n";
Using a "two-dimensional" block of text
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
Polyglot language example
Using "one-dimensional" string literals
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("function hello() {\n" +
" print('\"Hello, world\"');\n" +
"}\n" +
"\n" +
"hello();\n");
Using a "two-dimensional" block of text
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
function hello() {
print('"Hello, world"');
}
hello();
""");
Description
This section is identical to the same section in this JEP's predecessor, JEP 355, except for the addition of the subsection on new escape sequences.
A text block is a new kind of literal in the Java language. It may be used to denote a string anywhere that a string literal could appear, but offers greater expressiveness and less accidental complexity.
A text block consists of zero or more content characters, enclosed by opening and closing delimiters.
The opening delimiter is a sequence of three double quote characters ("""
) followed by zero or more white spaces followed by a line terminator. The content begins at the first character after the line terminator of the opening delimiter.
The closing delimiter is a sequence of three double quote characters. The content ends at the last character before the first double quote of the closing delimiter.
The content may include double quote characters directly, unlike the characters in a string literal. The use of \"
in a text block is permitted, but not necessary or recommended. Fat delimiters ("""
) were chosen so that "
characters could appear unescaped, and also to visually distinguish a text block from a string literal.
The content may include line terminators directly, unlike the characters in a string literal. The use of \n
in a text block is permitted, but not necessary or recommended. For example, the text block:
"""
line 1
line 2
line 3
"""
is equivalent to the string literal:
"line 1\nline 2\nline 3\n"
or a concatenation of string literals:
"line 1\n" +
"line 2\n" +
"line 3\n"
If a line terminator is not required at the end of the string, then the closing delimiter can be placed on the last line of content. For example, the text block:
"""
line 1
line 2
line 3"""
is equivalent to the string literal:
"line 1\nline 2\nline 3"