Return to site

Java Text Blocks Guidelines

· java
G1. You should use a text block when it improves the clarity of the code, particularly with multi-line strings.
// ORIGINAL
String message = "'The time has come,' the Walrus said,\n" +
                 "'To talk of many things:\n" +
                 "Of shoes -- and ships -- and sealing-wax --\n" +
                 "Of cabbages -- and kings --\n" +
                 "And why the sea is boiling hot --\n" +
                 "And whether pigs have wings.'\n";

// BETTER
String message = """
    'The time has come,' the Walrus said,
    'To talk of many things:
    Of shoes -- and ships -- and sealing-wax --
    Of cabbages -- and kings --
    And why the sea is boiling hot --
    And whether pigs have wings.'
    """;
G2. If a string fits on a single line, without concatenation and escaped newlines, you should probably continue to use a string literal.
// ORIGINAL - is a text block helpful here?
String name = """
              Pat Q. Smith""";

// BETTER - a string literal works fine
String name = "Pat Q. Smith";
G3. Use embedded escape sequences when they maintain readability.
var data = """
    Name | Address | City
    Bob Smith | 123 Anytown St\nApt 100 | Vancouver
    Jon Brown | 1000 Golden Place\nSuite 5 | Santa Ana
    """;
G4. For most multi-line strings, place the opening delimiter at the right end of the previous line, and place the closing delimiter on its own line, at the left margin of the text block.
String string = """
    red
    green
    blue
    """;
G5. Avoid aligning the opening and closing delimiters and the text block's left margin. This requires reindentation of the text block if the variable name or modifiers are changed.
// ORIGINAL
String string = """
                red
                green
                blue
                """;

// ORIGINAL - after variable declaration changes
static String rgbNames = """
                         red
                         green
                         blue
                         """;

// BETTER
String string = """
    red
    green
    blue
    """;

// BETTER - after variable declaration changes
static String rgbNames = """
    red
    green
    blue
    """;
G6. Avoid in-line text blocks within complex expressions, as doing so can distort readability. Consider refactoring to a local variable or to a static final field.
// ORIGINAL
String poem = new String(Files.readAllBytes(Paths.get("jabberwocky.txt")));
String middleVerses = Pattern.compile("\\n\\n")
                             .splitAsStream(poem)
                             .match(verse -> !"""
                                   ’Twas brillig, and the slithy toves
                                   Did gyre and gimble in the wabe;
                                   All mimsy were the borogoves,
                                   And the mome raths outgrabe.
                                   """.equals(verse))
                             .collect(Collectors.joining("\n\n"));

// BETTER
String firstLastVerse = """
    ’Twas brillig, and the slithy toves
    Did gyre and gimble in the wabe;
    All mimsy were the borogoves,
    And the mome raths outgrabe.
    """;
String poem = new String(Files.readAllBytes(Paths.get("jabberwocky.txt")));
String middleVerses = Pattern.compile("\\n\\n")
                             .splitAsStream(poem)
                             .match(verse -> !firstLastVerse.equals(verse))
                             .collect(Collectors.joining("\n\n"));
G7. Either use only spaces or only tabs for the indentation of a text block. Mixing white space will lead to a result with irregular indentation.
//ORIGINAL
    String colors = """
········red
␉       green
········blue""";
//result: "·······red\ngreen\n·······blue"

//PROBABLY WHAT WAS INTENDED
    String colors = """
········red
········green
········blue""";
//result: "red\ngreen\nblue"

G8. When a text block contains sequences of three or more double quotes, escape the first double quote of every run of three double quotes.

// ORIGINAL
String code = """
    String source = \"\"\"
        String message = "Hello, World!";
        System.out.println(message);
        \"\"\";
    """;

// BETTER
String code = """
    String source = \"""
        String message = "Hello, World!";
        System.out.println(message);
        \""";
    """;
G9. Most text blocks should be indented to align with neighbouring Java code.
// ORIGINAL
String code = """
    String source = \"\"\"
        String message = "Hello, World!";
        System.out.println(message);
        \"\"\";
    """;

// BETTER
String code = """
    String source = \"""
        String message = "Hello, World!";
        System.out.println(message);
        \""";
    """;
G10. It is recommended to fully left justify a wide string in order to avoid horizontal scrolling or line wrapping.
// ORIGINAL

class Outer {
    class Inner {
        void printPoetry() {
            String lilacs = """
                Over the breast of the spring, the land, amid cities,
                Amid lanes and through old woods, where lately the violets peep’d from the ground, spotting the gray debris,
                Amid the grass in the fields each side of the lanes, passing the endless grass,
                Passing the yellow-spear’d wheat, every grain from its shroud in the dark-brown fields uprisen,
                Passing the apple-tree blows of white and pink in the orchards,
                Carrying a corpse to where it shall rest in the grave,
                Night and day journeys a coffin.
                """;
            System.out.println(lilacs);
        }
    }
}

// BETTER

class Outer {
    class Inner {
        void printPoetry() {
            String lilacs = """
Over the breast of the spring, the land, amid cities,
Amid lanes and through old woods, where lately the violets peep’d from the ground, spotting the gray debris,
Amid the grass in the fields each side of the lanes, passing the endless grass,
Passing the yellow-spear’d wheat, every grain from its shroud in the dark-brown fields uprisen,
Passing the apple-tree blows of white and pink in the orchards,
Carrying a corpse to where it shall rest in the grave,
Night and day journeys a coffin.
""";
            System.out.println(lilacs);
        }
    }
}
G11. Similarly, it is also reasonable to fully left justify a text block when a high line count causes the closing delimiter is likely to vertically scroll out of view. This allows the reader to track indentation with the left margin when the closing delimiter is out of view.
// ORIGINAL

String validWords = """
                    aa
                    aah
                    aahed
                    aahing
                    aahs
                    aal
                    aalii
                    aaliis
...
                    zythum
                    zythums
                    zyzzyva
                    zyzzyvas
                    zzz
                    zzzs
                    """;


// BETTER

String validWords = """
aa
aah
aahed
aahing
aahs
aal
aalii
aaliis
...
zythum
zythums
zyzzyva
zyzzyvas
zzz
zzzs
""";

G12. The \<line-terminator> escape sequence should be used when a text block's final new line needs to be excluded. This better frames the text block and allows the closing delimiter to manage indentation.

// ORIGINAL

String name = """
    red
    green
    blue""".indent(4);


// BETTER

String name = """
        red
        green
        blue\
    """;