Text Blocks

Quick summary:

  • Text blocks simplify the creation of multiline strings without the need for most escape sequences, making code easier to write and maintain.
  • Released in Java 15 (2020), but introduced in Java 13 (2019).

Key Features

  • Multiline Strings: Enables writing string literals that span several lines of source block, without explicit line terminators like \n.
  • Automatic Formatting: Preserves the natural formatting of the text within the block, respecting newlines and spaces.
  • Fewer Escape Sequences: Reduces the need for escape sequences such as new line (\n) and tab (\t) and quotes (\"), as these are naturally handled within the delimiters of a text block.
  • Syntax: Text blocks start and end with triple quotes """, allowing easy embedding of complex multiline texts without concatenation.

Example

Before Java 17:

Before, you had to work with crazy concatenations and escape sequences, creating an unreadable soup (not to mention inefficient).

String json = "{\n" +
    "\"name\": \"Java\",\n" +
    "\"version\": \"17\",\n" +
    "\"year\": 2021\n" +
"}";

After Java 17:

With the new pattern matching, the use of instanceof immediately automatically casts the object to that type.

String json = """
    {
        "name": "Java",
        "version": "17",
        "year": 2021
    }
    """;

👩‍💻 Hands-on Demo: Text Blocks

1. HTML Snippet

  1. In the main-method of a TextBlocksHtmlDemo-class, declare a String-variable called “htmlBefore“, and assign to it a small HTML page written using traditional String literals.
  2. Underneath that, declare a new String-variable called “htmlAfter“, and assign to it the same small HTML page but this time using a text block.
  3. Notice the reduction in complexity and improvement in readability.

2. SQL Query

  1. In the main-method of a TextBlocksSqlQueryDemo-class, refactor the following code into a single text block:
String query = "SELECT name, version" +
        "FROM modules WHERE " +
        "year = 2020 AND active = TRUE;";

3. JSON

  1. Create a Pokemon-class with a name, height and weight.
  2. In a TextBlocksPokeApiDemo-class, write a convertPokemonToJson-method that accepts a Pokemon-object and returns it as a String in JSON-format.
    • Use text blocks to make this more readable.
  3. Make a Pokemon-object and print the result of passing it to our conversion method.

Solutions

🕵️‍♂️ Click here to reveal the solutions

1. HTML Snippet

public class TextBlocksHtmlDemo {
    public static void main(String[] args) {
        // Traditional way
        String htmlBefore = "<html>\n" +
                "    <body>\n" +
                "        <h1>Welcome to Java Evolution!</h1>\n" +
                "    </body>\n" +
                "</html>";

        // Using text blocks
        String htmlAfter = """
                <html>
                    <body>
                        <h1>Welcome to Java Evolution!</h1>
                    </body>
                </html>
                """;
    }
}

2. SQL Query

public class TextBlocksSqlQueryDemo {
    public static void main(String[] args) {
        // Before using text blocks
        String query = "SELECT name, version" +
                "FROM modules WHERE " +
                "year = 2020 AND active = TRUE;";

        // After using text blocks
        String queryBlock = """
                SELECT name, version
                FROM modules
                WHERE year = 2020 AND active = TRUE;
                """;
    }
}

3. JSON

public class TextBlocksPokeApiDemo {
    public static void main(String[] args) {
        Pokemon pokemon = new Pokemon("Pikachu", 100, 5);
        String pokemonJson = convertPokemonToJson(pokemon);

        System.out.println(pokemonJson);
    }

    private static String convertPokemonToJson(Pokemon pokemon) {
        return String.format("""
                {
                    "name": "%s",
                    "weight": %d,
                    "height": %d
                }
                """, pokemon.getName(), pokemon.getWeight(), pokemon.getHeight());
    }
}
public class Pokemon { // Record would be better
    private String name;
    private int weight;
    private int height;

    public Pokemon(String name, int weight, int height) {
        this.name = name;
        this.weight = weight;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}
public record Pokemon(String name, int weight, int height) {
}