Java 中的文本块或多行字符串功能是什么?

问题描述

Java SE 13 引入了 Text Blocks(或多行字符串)功能。它与现有的字符串表示有什么区别和相似之处?

解决方法

什么是文本块?

A text block 是一个多行字符串文字,该功能提供了一种干净的方式来以可预测的方式格式化字符串,而无需使用大多数转义序列。它以 """(三个双引号)开头和结尾,例如

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!

是否仅作为预览功能提供?

它在 Java SE 13 和 Java SE 14 中作为预览功能仍然可用,并已在 Java SE 15 中标准化。对于 Java SE 13 和 14,就像任何预览功能 em>,它必须用 --enable-preview 选项编译和执行,例如

编译:

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

执行:

java --enable-preview Main

它们是否存储在字符串池中?

是的,他们是。 文本块被编译成与传统String值相同的类型,即字节码不区分传统String值和文本块.

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

输出:

true

一个文本块可以与另一个字符串连接吗?

是的,一个文本块可以连接到一个传统的字符串值或另一个文本块,以同样的方式连接传统的 String 值。如上所述,字节码不区分传统的 String 值和文本块

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));
    }
}

输出:

Hello World!
Hello World! Java rocks!

请注意,我在 Hello 中的 str1 之后放置了空格,并在 Java rocks! 中的 str3 之前放置了另一个空格。

是否支持转义序列

是的,转义序列将以传统方式进行评估,例如

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);
    }
}

输出:

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

是否支持可替换参数?

是的,您可以使用 %s$<<replaceable-parameter>> 替换文本块中的参数,如下所示:

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,"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"));
    }
}

输出:

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?

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...