Java 13带来了带有文本块的多行字符串

Java 13带来了带有文本块的多行字符串

今天,Java 13将会发布。除了其他相当不引人注目的创新之外,该版本还通过多线字符串文字扩展了语言,使用JEP 355引入的Java术语文本块或文本块。日志记录是生成更长文本输出,创建片段的好方法。其他语言,如HTML或JSON – 这将使一些测试更具可读性 – 甚至可以制定SQL语句。

例如:

相比之下,结果与这个经典和更令人不愉快的变体相同:

在Java 13中使用文本块之前,必须解锁它们,因为它们最初仅作为功能预览包含在内。要在命令行或构建工具中进行编译和执行,必须将参数-enable预览附加到java和javac。在Eclipse中,编译器选项中有相应的设置。在Intellij IDEA中,必须适当选择模块的语言级别。

文本块的三个引号

文本块可以在任何其他地方使用,其中接受经典字符串文字“喜欢这个”并且它们具有简单的语法:

他们以三个引号和一个换行符开头。它们以三个引号结尾,或者在块的最后一行或者在单独的行上。在字符串中,转义序列被解释为通常的,因此字符串不是原始的。

块开头的换行符不会成为终止字符串的一部分。如果右引号位于各自的行中,则字符串以换行符结束;此行中的空格字符(例如空格和制表符)永远不会成为字符串的一部分。

由于文本块上下文中的单引号没有句法含义,因此特别是不要结束它,因此不需要转义。这消除了通常的转义序列源,使得在Java中嵌入HTML或JSON等语言变得更加容易。

如果源代码中有文本块,那么编译器的工作当然是处理它。怎么样,照亮下一页。但是简单地谈谈结果是有意义的。

文本块和字符串文字是无法区分的

如果编译器检查了块并将其转换为字符串,则结果与具有相同内容的公共字符串文字无法区分。在上面的例子中,这意味着jsonBlock.equals(jsonPhrase)为true。

但是编译器又向前迈进了一步。字符串常量在编译时进行重复数据删除,以便在运行时节省内存。结果,相同的文字不仅相等,而且等于==。如果代码中的许多位置出现相同的片段,这很方便,但如果您忘记了这些片段,可能会非常不舒服,例如,使用字符串作为锁定。

无论是使用文字块还是文本块创建字符串,都会使用此机制。这意味着即使jsonBlock == jsonPhrase也是如此。因此,文本块是纯粹的编译器功能,在运行时,您无法分辨代码中如何定义字符串实例。

行结束的规范化

文本块的一个有趣方面是包含源代码的文本文件的属性与代码的语义混合在一起。显然,行结尾会发生这种情况:以 r n结尾的行(在Windows上是常见的)还是 n(在Unix上常见的LF)是一个仅配置问题,但如果编译器默认超越,那将会影响生成的字符串 – 这会很不舒服。这同样适用于行尾的空格字符,因为它们很少可见,并且它们在字符串中的采用很容易引起混淆。

因此,编译器通过删除最后一个字符后面的所有空格字符并用 n替换所有换行组合(即 r, r n, n和 n)来规范化行结尾。由于正常计算转义序列(在此归一化之后),因此可以通过以序列 r n结束行来生成CRLF:

它比压痕处的线端更令人兴奋,更复杂。在这里,开发人员和编译器必须区分偶然和有意的缩进:由于格式化而导致的代码缩进应该对创建的字符串没有影响 – 这是无关紧要的。但是,进一步的缩进应该被认为是有意的并且反映在结果中。

缩进和格式化文本块

在前面的示例中,jsonBlock表示开始和结束括号应位于其各自行的开头,而其间的三行各自使用制表符缩进。

为了实现这一点,编译器应用了一种不感兴趣的算法,它具有以下效果:

1.所有空格字符都被视为相同 – 特别是像标签一样的空格。
2.所有空的空行都用于删除相同数量的前导空格字符,以至于至少有一行不再以这样的字符开头。
3.如果结束引号位于各自的行中,则在上一步中也会考虑这一点。

点2使jsonBlock包含所需的结果。因为无论代码缩进多远,该缩进都被识别为边缘并被删除。但是,如果所有行都缩进并且应该以制表符开头,该怎么办呢?

缩进因格式而异

如果要更改缩进,则第3点起作用:由于在确定要删除的字符时会考虑带有右引号的行,因此不会删除比最后一行包含的空格字符更多的空格字符。实际上,其他行与右引号对齐。如果他们进一步参与,这反映在结果中。

在此示例中,确定缩进时考虑的六行以2,3,3,3,2或1制表符开头。编译器将删除选项卡。因此,所有其他线条保持缩进,有一个选项卡(打开和关闭括号)或两个选项卡(其余三个线)。

因为,对于额外的缩进,行内容必须相对于右引号定位,这意味着“”“必须在一个单独的行中,正如我们在开头提到的那样,这取决于最后的换行符字符串,如果你想要缩进,但不是换行符,这是类String的新方法发挥作用的地方。

缩进各不相同 – 使用字符串方法

从Java 12开始,有一个String :: indent方法用于缩进具有给定空格数的字符串的所有行:

在jsonIndentMethod中,开始和结束括号前面有四个空格。其他三行有些令人困惑:根据源代码的格式,它们以四个空格加上缩进开头。如果这是四个空格缩进,这是非常好的。但是,如果有两个空格或一个标签,则产生的缩进有点颠簸。不幸的是,没有方便的解决方案。

但是,假设有四个空格的缩进,jsonIndentMethod几乎与jsonIndentBlock相同。唯一的区别是后者以换行结束。如果你不想要它并且仍然需要在每行之前缩进,你可以按照描述访问String :: indent。

另外,在Java 13中添加了String :: stripIndent。此方法根据与编译器相同的逻辑删除缩进。在以下字符串indentedJsonLiteral中,每行都缩进至少一个选项卡:

额外的选项卡使indentedJsonLiteral不等于介绍性的jsonBlock,但stripIndent

格式化文本块

Oracle的Jim Laskey和Stuart Marks编写了一本开发人员指南,介绍值得阅读的文本块。它包含这十个建议(略有改写,没有第十一个):

1.应该使用文本块来提高代码的可读性,特别是在多行字符串中。
2.如果没有连接和插入 n的字符串适合一行,它应该被定义为文字。
3.如果提高可读性,则不反对在文本块中使用 n等转义序列。
4.在大多数情况下,三个开头的引号应该在它们的行尾,而三个引号应该在它们自己的行中。
5.文本行和右引号不应与开头引号对齐。
6.为了便于阅读,它们最好更好地保存在局部变量或静态常量中,而不是在更复杂的表达式(如流管道)中使用文本块。
7.由于制表符和空格的等同处理,文本块只能用两个字符中的一个缩进,以避免不均匀的结果。
8.如果一个文本块连续包含三个以上的引号,则逃避三个中的第一个就足够了。
9.默认情况下,应根据标准格式对齐文本行。
10.如果文本块包含非常长的行,则可以通过将行对齐到最左侧来防止水平滚动。

这不仅包括语法,重复数据删除,行结尾标准化和处理缩进等技术注意事项,还包括风格问题。这篇博文中有关于文本块的更多信息。

Java 13还有什么?对于大多数开发人员来说,文本块肯定是Java 13中最有趣的功能,但也有一些其他更改。首先,Java 12中引入的switch表达式已得到改进:返回值 – 例如,在较长语句块的末尾 – 现在返回yield而不是break。

资讯来源:由0x资讯编译自REVYUH。版权归作者所有,未经许可,不得转载
提示:投资有风险,入市需谨慎,本资讯不作为投资理财建议。请理性投资,切实提高风险防范意识;如有发现的违法犯罪线索,可积极向有关部门举报反映。
你可能还喜欢