JDK13中将增长文本块特性

摘要

JDK13中将加入文本块功能。 本篇文章将有如下内容:html

  1. 新版JDK中加入文本块的动机是什么?
  2. 文本块如何使用
  3. 文本块的编译
  4. 文本块的链接

目标

  • 简化跨越多行的字符串,避免对换行等特殊字符进行转义,简化编写Java程序。
  • 加强Java程序中字符串的可读性。

动机

在Java中,一般须要使用String类型表达HTML,XML,SQL或JSON等格式的字符串,在进行字符串赋值时须要进行转义和链接操做,而后才能编译该代码,这种表达方式难以阅读而且难以维护。java

不管文本是来自其余编程语言的代码,仍是天然语言,在Java程序中表示短文本,中文本和长文本须要有通用的表达方式。程序员

所以,文本块将提升Java程序的可读性和可写性。编程

HTML example

没有文本块时:bash

String html = "<html>\n" +
              " <body>\n" +
              " <p>Hello, world</p>\n" +
              " </body>\n" +
              "</html>\n";
复制代码

使用文本块后微信

String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;
复制代码

SQL example

没有文本块时:less

String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
               "WHERE `CITY` = 'INDIANAPOLIS'\n" +
               "ORDER BY `EMP_ID`, `LAST_NAME`;\n";
复制代码

使用文本块后编程语言

String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'INDIANAPOLIS'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;
复制代码

描述

文本块是Java语言中的一种新文字。它能够用来表示任何字符串,而且提供更大的表现力和更少的复杂性。ide

文本块由零个或多个字符组成,由开始和结束分隔符括起来。学习

开始分隔符是由三个双引号字符("""),后面能够跟零个或多个空格,最终以行终止符结束。文本块内容以开始分隔符的行终止符后的第一个字符开始。

结束分隔符也是由三个双引号字符表示,文本块内容以结束分隔符的第一个双引号以前的最后一个字符结束。

文本块中的内容能够直接使用","可使用,但不是必需的。

文本块中的内容能够直接包括行终止符。容许在文本块中使用\ n,但不是必需的。例如,文本块:

""" line 1 line 2 line 3 """
复制代码

至关于:

"line 1\nline 2\nline 3\n"
复制代码

或者一个链接的字符串:

"line 1\n" +
"line 2\n" +
"line 3\n"
复制代码

若是字符串末尾不须要行终止符,则结束分隔符能够放在最后一行内容上。例如:

""" line 1 line 2 line 3"""
复制代码

至关于:

"line 1\nline 2\nline 3"
复制代码

文本块能够表示空字符串,但不建议这样作,由于它须要两行源代码:

String empty = """ """;
复制代码

如下示例是错误格式的文本块:

String a = """""";   // 开始分隔符后没有行终止符
String b = """ """;  // 开始分隔符后没有行终止符
String c = """ ";        // 没有结束分隔符
String d = """ abc \ def """;      // 含有未转义的反斜线(请参阅下面的转义处理)
复制代码

编译处理

文本块是String类型的常量表达式,就像字符串同样。 可是,与字符串不一样,Java编译器分为三个步骤来处理文本块的内容:

  1. 内容中的行终止符被转换为LF(\ u000A)。此转换的目的是在跨平台移动Java源代码时遵循最小惊喜原则
  2. 为了匹配Java源代码的缩进,将内容中的多余的空格删除。
  3. 解释内容中的转义字符。这做为最后一步意味着开发人员能够编写转义字符,例如\n,而不会被以前的步骤修改或删除。

最小惊喜原则:老是作最不使人意外的事情

处理后的内容做为常量池中的CONSTANT_String_info条目记录在类文件中,就像字符串同样。

在运行时,文本块将被实例化为String的实例,就像字符串同样。从文本块派生的String实例与从字符串派生的实例是没法区分的。具备相同内容的两个文本块将引用相同的String实例,就像字符串同样。

如下部分将更详细地讨论了编译时的处理。

行终止符

文本块内容中的行终止符由Java编译器把CR(\ u000D)和CRLF(\ u000D \ u000A)标准化为LF(\ u000A)。这样确保了文本块内容在不一样平台上是等效的。

多余的空格

下面这段代码中,咱们用.来表示咱们代码中的的空格,而这些位置的空格就是多余的。

String html = """
..............<html>
..............    <body>
..............        <p>Hello, world</p>
..............    </body>
..............</html>
..............""";
复制代码

多余的空格还会出如今每一行的结尾,特别是当你从其余地方复制过来时,更容易出现这种状况,好比下面的代码:

String html = """
..............<html>...
..............    <body>
..............        <p>Hello, world</p>....
..............    </body>.
..............</html>...
..............""";
复制代码

这些多余的空格对于程序员来讲是看不到的,可是他又是实际存在的,因此若是编译器不作处理,可能会致使程序员看到的两个文本块内容是同样的,可是这两个文本块却由于存在这种多余的空格而致使差别,好比哈希值不相等。

因此编译器在编译时会删除掉这些多余的空格。

转义字符

容许开发人员使用\ n,\ f和\ r来进行字符串的垂直格式化,使用\ b和\ t进行水平格式化。好比下面的代码是合法的:

String html = """
              <html>\r
                  <body>\r
                      <p>Hello, world</p>\r
                  </body>\r
              </html>\r
              """;
复制代码

请注意,在文本块内自由使用"是合法的,即便在开始或结束分隔符旁边也是如此。例如:

String story = """
    "When I use a word," Humpty Dumpty said,
    in rather a scornful tone, "it means just what I
    choose it to mean - neither more nor less."
    "The question is," said Alice, "whether you
    can make words mean so many different things."
    "The question is," said Humpty Dumpty,
    "which is to be master - that's all."""";
复制代码

可是,三个"字符的序列须要进行转义至少一个"以免模仿结束分隔符:

String code = 
    """
    String text = \"""
        A text block inside a text block
    \""";
    """;
复制代码

文本块链接

能够在任何可使用字符串的地方使用文本块。例如,文本块和字符串能够相互链接:

String code = "public void print(Object o) {" +
              """
                  System.out.println(Objects.toString(o));
              }
              """;
复制代码

可是,涉及文本块的链接可能变得至关笨重。如下面文本块为基础:

String code = """
              public void print(Object o) {
                  System.out.println(Objects.toString(o));
              }
              """;
复制代码

假设咱们想把上面的Object改成来至某一变量,咱们可能会这么写:

String code = """
              public void print(""" + type + """
               o) {
                  System.out.println(Objects.toString(o));
              }
              """;
复制代码

能够发现这种写法可读性是很是差的,更简洁的替代方法是使用String :: replace或String :: format,好比:

String code = """
              public void print($type o) {
                  System.out.println(Objects.toString(o));
              }
              """.replace("$type", type);
复制代码
String code = String.format("""
              public void print(%s o) {
                  System.out.println(Objects.toString(o));
              }
              """, type);
复制代码

另外一个方法是使用String :: formatted,这是一个新方法,好比:

String source = """
                public void print(%s object) {
                    System.out.println(Objects.toString(object));
                }
                """.formatted(type);
复制代码

参考:openjdk.java.net/jeps/355

总结

本文写在JDK13还未正式发布以前,也是但愿能让你们先睹为快,同时但愿JDK13能尽快发布,让咱们Javer能用上更方便的语言。 若是以为这篇文章能让你学到知识,可否帮忙转发,将知识分享出去。 若是想第一时间学习更多的精彩的内容,请关注微信公众号:1点25

相关文章
相关标签/搜索