Что такое функция текстовых блоков (или многострочных строк) в Java? [закрыто]

В Java SE 13 появилась функция текстовых блоков (или многострочных строк). В чем его отличия и сходства с существующим строковым представлением?

1 ответ

Решение

Что такое текстовый блок?

Текстовый блок представляет собой многострочный строковый литерал и функция предлагает чистый способ форматирования строки в предсказуемым образом, без использования большинства управляющих последовательностей. Он начинается и заканчивается """ (три двойных кавычки) например

      public class Main {
    public static void main(String[] args) {
        String text = """
                <html>
                    <head>
                        <title>Hello World</title>
                    </head>
                    <body>
                        Java rocks!
                    </body>
                </html>""";

        System.out.println(text);
    }
}

Выход:

      <html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
        Java rocks!
    </body>
</html>

В традиционном строковом представлении код будет выглядеть так:

      public class Main {
    public static void main(String[] args) {
        String text = "<html>\n"
                + " <head>\n"
                + "     <title>Hello World</title>\n"
                + " </head>\n"
                + " <body>\n"
                + "     Java rocks!\n"
                + " </body>\n"
                + "</html>";

        System.out.println(text);
    }
}

Еще одно ключевое отличие состоит в том, что текстовый блок начинается с трех символов двойных кавычек, за которыми следует признак конца строки, чего нет в традиционном строковом представлении. Это значит

  1. Текстовый блок нельзя помещать в одну строку.

  2. Содержимое текстового блока не может следовать за тремя открывающими двойными кавычками в одной строке.

            String str = "Hello World!"; // The traditional string
    
    String textBlock = """
            Hello World!
            """; // The text block
    
    String notAllowed = """Hello World!"""; // Error
    
    // The following code will fail compilation
    String notAllowed2 ="""Hello
             World!
            """;
    

Примечание об отступе:

Компилятор сдвигает весь текстовый блок влево, а затем сохраняет указанный интервал.

      String str1 = """
   Hello""";
^^^<-----These three whitespace characters will be retained

Демо:

      public class Main {
    public static void main(String[] args) {
        // Text block without a line break at the end
        String str1 = """
                Hello""";

        // Text block with a line break at the end
        String str2 = """
                Hello
                """;

        // Text block with three whitespace in the beginning and a line break at the end
        String str3 = """
                   World!
                """;
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
        System.out.println("Java rocks!");
    }
}

Выход:

      Hello
Hello

   World!

Java rocks!

Is it available only as a Preview Feature?

It remained available in Java SE 13 and Java SE 14 as a Preview Feature and has been standardised with Java SE 15. With Java SE 13 and 14, like any Preview Feature, it has to be compiled and executed with --enable-preview option e.g.

To compile:

      javac --enable-preview --release 13 Main.java

To execute:

      java --enable-preview Main

Are they stored in string pool?

Yes, they are. The text blocks are compiled to the same type as that of the traditional value i.e. the byte code does not distinguish between a traditional value and text block.

      public class Main {
    public static void main(String[] args) {
        String str1 = "Hello World!";
        String str2 = """
                Hello World!""";
        System.out.println(str1 == str2);
    }
}

Output:

      true

Can a text block be concatenated with another string?

Yes, a text block can be concatenated to a traditional string value or another text block in the same way, the traditional values are concatenated. As already described above, the byte code does not distinguish between a traditional String value and text block.

      public class Main {
    public static void main(String[] args) {
        String str1 = "Hello ";
        String str2 = """
                World!""";
        String str3 = """
                 Java rocks!
                """;
        System.out.println(str1 + str2);
        System.out.println(str1 + (str2 + str3));
    }
}

Output:

      Hello World!
Hello World! Java rocks!

Note that I have put whitespace after Hello in str1 and another whitespace before Java rocks! in str3.

Does it support Escape Sequences?

Yes, the escape sequences will be evaluated in the traditional way e.g.

      public class Main {
    public static void main(String[] args) {
        String text = """
                <html>
                    <head>
                        <title>Hello World</title>
                    </head>
                    <body>
                        Java\n\t\trocks!
                    </body>
                </html>""";

        System.out.println(text);
    }
}

Output:

      <html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
        Java
        rocks!
    </body>
</html>

Does it support replaceable parameter?

Yes, you can replace a parameter in the text block using %s or $<<replaceable-parameter>> as shown below:

      public class Main {
    public static void main(String[] args) {
        String text = """
                What is the distance between %s and %s?""";

        System.out.println(String.format(text, "earth", "moon"));
        System.out.println(String.format(text, "earth", "mercury"));

        // Alternative-1
        text = """
                What is the distance between $celestial1 and $celestial2?""";

        System.out.println(text.replace("$celestial1", "earth").replace("$celestial2", "moon"));

        // Alternative-2 using the deprecated String#formatted
        text = """
                What is the distance between %s and %s?""";
        System.out.println(text.formatted("earth", "moon"));
    }
}

Output:

      What is the distance between earth and moon?
What is the distance between earth and mercury?
What is the distance between earth and moon?
What is the distance between earth and moon?
Другие вопросы по тегам