Blog

The latest expert opinions, articles, and guides for the Java professional.

Using Text Blocks in Java 13

Introduced in JDK 13, the text blocks preview language feature introduce a way for developers to predictably format multi-line string literals while avoiding most escape sequences.

The preview feature began as work on the (now deprecated) JDK Enhancement Proposal 326: raw string literals.

JEP 326: Raw String Literals

Raw string literals were to be introduced in JDK 12 as exploratory preview feature under JEP 326. It added raw string literals to Java to help developers avoid escapes – a common issue when writing strings.

In December of 2018, the proposal was withdrawn due to feedback from the community. They pointed to issues with the backslash being too lightweight typographically, and the “any number of quotes” rule being counter to a tool-friendly philosophy – among other feedback.

JEP 355: Text Blocks

In 2019, JEP 355 added a more concrete vision for how Raw String Literals will work in Java, including considerations for formatting, readability, and decreasing the frequency and necessity of escape sequences.

JEP 368: Text Blocks (Second Preview)

The main updates in JEP 368: Text Blocks (Second Preview) are adding two new escape sequences – \s and \<line-terminator> which add a necessary level of simplicity for text blocks.

New Features in JDK 13 Text Blocks

As mentioned above, the biggest feature of JEP 355: Text Blocks is the ability to use multi-line string literals in Java. This is a feature that is currently available with most programming languages and that Java has caught up with this release.

Another important consideration in JEP 355 is the effort to make inline multi-line Strings more readable. Because of that, text blocks eliminate the need to concatenate multiple strings together, escape nested quotation marks, or include newline markers.

Opening and Closing Delimiters

Because text blocks exist in addition to string literals, the development team needed a way to visually separate text blocks and string literals. They chose the fat delimiters """, with the opening delimiter followed by a line terminators, as shown in the below example.

"""
line 1
line 2
line 3
"""

In instances where the line terminator isn’t required at the end of a string, the closing delimiter can appear in line on the closing line.

"""
line 1
line 2
line 3"""

Incidental White Space

Indentation is removed so the line with the least white space characters is used to determine how many white space characters should be removed from every line.

The compiler takes whitespace indentation into consideration, differentiating incidental whitespaces from essential whitespaces.

Text Blocks Example of Incidental White Space

In the example above, we see that the least spaced line sets the indent.

So, the code:

class Foo { 
  public void bar() {    
    String txt = """      
      Some        
        Nested          
          Text        
        Is     
      Here      
      """;  
  }
}

Would be equivalent to:

class Foo {
  public void bar() {
    String txt =
      "Some\n" +
      "  Nested\n" +
      "    Text\n" +
      "  Is\n" +
      "Here\n";
  }
}

When you remove two spaces from in front of the closing delimiter, you see the indent decrease two spaces across the text block.

Text Blocks Example With Incidental White Space Part 2

So for the code:

class Foo { 
 public void bar() {    
   String txt = """      
     Some        
       Nested          
         Text        
       Is     
     Here      
   """;  
 }
}

Would then be equivalent to:

class Foo {
  public void bar() {
    String txt =
      "  Some\n" +
      "    Nested\n" +
      "      Text\n" +
      "    Is\n" +
      "  Here\n";
 }
}

Escape Sequences

Text Blocks handle escape sequences the same way they were handled with string literals allowing you to use the same escape sequences. Should you have the need to translate escape sequences in text directly, for instance reading from a resource file, a method was added to the String class to do this:

str.translateEscapes()

When using \n, \f, and \r, escape sequences as the final step, developers can vertically format the string without affecting how line terminators are translated.

\b and \t, on the other hand, can be used to horizontally format a string without affecting the incidental white space we talked about in the previous example.

Using Quotation Marks Inside Text Blocks

Another thing that text blocks (smartly) account for is the use of quotation marks inside text blocks. As noted in the JEP 355 article, quotation marks can be used at will inside a text block – unless they appear in direct sequence. To not be confused with the closing delimiter, when they do appear in sequence, they need to be escaped – as shown in the JEP 355 example:

String code = """
    String text = \"""
        A text block inside a text block
        \""";
    """

Additional Escape Sequences in JEP 368

Acting on feedback from the JDK 13 release, JEP 368 introduces two new text block-specific escape sequences which don’t apply to ordinary string literals.

\ <line-terminator> Escape Sequence

The \ <line-terminator> escape sequence is used to explicitly suppress the insertion of a new line character.
In the example provided in JEP 368, we see how a string, which has been concatenated into substrings, is then wrapped onto separate lines.

String text = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
              "elit, sed do eiusmod tempor incididunt ut labore " +
              "et dolore magna aliqua.";

And again, using the new \ <line-terminator> escape sequence”

String text = """
                Lorem ipsum dolor sit amet, consectetur adipiscing \
                elit, sed do eiusmod tempor incididunt ut labore \
                et dolore magna aliqua.\
                """;

\s – Escape Sequence

The \s escape sequence translates to a single space – which isn’t processed until after incidental white space is stripped. This example provided in JEP 368 shows how that may be used:

String colors = """
    red  \s
    green\s
    blue \s
    """;

Concatenation with Text Blocks

Another nice feature for text blocks involves a readability improvement for concatenation inside a text block.

Instead of making developers leave long, awkward segments of white space between lines, they instead recommend developers to use the String methods replace and format, or the new instance method formatted.

New Methods in Text Blocks

The new String instance methods included with Text Blocks in JDK 13 are (marked as deprecated until it’s out of preview):

  • str.formatted(args)

    – equivalent to String.format(str, args)

  • str.stripIndent()

    – Equivalent to what the compiler does to remove indentation

  • str.translateEscapes()

    – Translates escape sequences (noted in the list above) into their character representation.

Additional Resources

If you want to learn more about text blocks, and how or where to best use them, I recommend reading “The Programmer’s Guide to Text Blocks” by Jim Laskey and Stuart Marks.

If you’re looking for additional information on the JDK 13 preview language features, I recently published a blog on switch expressions, here.

Lastly, if you want to see a recorded demonstration of some of the examples I covered here and in the other article, you can watch my preview language features webinar here.

JRebel Supports Text Blocks and Switch Expressions in JDK 13

Lastly, we recently launched JRebel 2019.2.0, which fully supports JDK 13 – including use of text blocks and switch expressions.

You can try it out free for 10 days by clicking the link.

Try JRebel for Free

No Responses

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.