简体   繁体   English

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

[英]What is the Text Blocks (or Multiline Strings) feature in Java?

Java SE 13 introduced Text Blocks (or Multiline Strings) feature. Java SE 13 引入了文本块(或多行字符串)功能。 What are its differences and the similarities with the existing string representation?它与现有的字符串表示有什么区别和相似之处?

What is a text block?什么是文本块?

A text block is a multi-line string literal and the feature offers a clean way to format the string in a predictable way, without using most of the escape sequences. 文本块是多行字符串文字,该功能提供了一种干净的方式来以可预测的方式格式化字符串,而无需使用大多数转义序列。 It starts and ends with a """ (three double-quotes marks) eg它以""" (三个双引号)开头和结尾,例如

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

Output: Output:

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

With the traditional string representation, the code would look like使用传统的字符串表示,代码看起来像

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

Another key difference is that a text block begins with three double-quote characters followed by a line terminator which is not the case with the traditional string representation.另一个关键区别是文本块以三个双引号字符开头,后跟一个行终止符,这与传统的字符串表示不同。 It means它的意思是

  1. The text block can not be put on a single line.文本块不能放在一行上。

  2. The content of the text block can not follow the three opening double-quotes on the same line.文本块的内容不能跟在同一行的三个左双引号之后。

     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! """;

This was a much-needed feature in Java.这是 Java 中急需的功能。

A note about how it compares with text block in Kotlin (a modern JVM-based language)?关于它如何与 Kotlin(一种现代的基于 JVM 的语言)中的文本块进行比较的注释?

  • Kotlin does not have any of the two above mentioned constraints. Kotlin 没有上述两个约束中的任何一个。
  • Kotlin does not require escaping a \ inside the text block which makes writing a RegEx expression easier eg the following is a valid text block in Kotlin but invalid in Java: Kotlin does not require escaping a \ inside the text block which makes writing a RegEx expression easier eg the following is a valid text block in Kotlin but invalid in Java:
    var str = """
        \d{2}-\d{2}-\d{4}
        """

In Java, one will have to write it as在 Java 中,必须将其写为

var str = """
    \\d{2}-\\d{2}-\\d{4}
    """;

A note about indentation:关于缩进的说明:

The compiler shifts the complete text block to the left and then retains the specified spacing.编译器将整个文本块向左移动,然后保留指定的间距。

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

Demo:演示:

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

Output: Output:

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 eg 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例如

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 String value ie the byte code does not distinguish between a traditional String value and text block .文本块被编译为与传统String值相同的类型,即字节码不区分传统String值和文本块

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

Output: 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 String values are concatenated.是的,一个文本块可以连接到一个传统的字符串值或另一个文本块,就像连接传统的String值一样。 As already described above, the byte code does not distinguish between a traditional String value and text block .如上所述,字节码不区分传统的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));
    }
}

Output: Output:

Hello World!
Hello World! Java rocks!

Note that I have put whitespace after Hello in str1 and another whitespace before Java rocks!请注意,我在str1中的Hello之后放置了空格,在Java rocks! in str3 .str3中。

Does it support Escape Sequences ?它是否支持转义序列

Yes, the escape sequences will be evaluated in the traditional way eg是的,转义序列将以传统方式进行评估,例如

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: 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:是的,您可以使用%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, "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: 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?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM