Java 新技术:文字块
聊聊Java的进展和新技术,是我给自己在InfoQ写作平台设定的一个小目标。为了方便你检索、阅读,我以“Java新技术”作为这一类的文字标题的起始。
第一篇文章,我们聊聊Java的文字块。 如果你想练练手,本文代码可以从github下载。
文字块正式进入JDK
2020年4月2日,文字块提案获得了批准,正式成为JDK 15的一部分。4月15日,文字块的实现代码并入JDK 15。 你如果想要先睹为快,可以下载JDK 15的抢先体验版。
什么是文字块?
文字块是一个由多行文字构成的字符串。比如,下面的textBlock字符串就是通过文字块定义的。
为什么需要文字块?
为什么需要文字块呢? 其实,只要我们看看没有文字块的时候,应该怎么定义上面的字符串常量,我们就明白了。
如果使用普通的字符串,这样的字符串常量定义看起来像下面的样子。
要定义这样的多行的字符串常量,需要插入使用很多换行符以及字符串连接符。这样的格式看起来可没有文字块养眼,而且很容易出错。特别是要从别的地方拷贝一段HTML或者SQL语句,然后转换成上面格式的字符串,是不是出力多,收效少,需要特别的耐心?遗憾的是,这样的工作还特别多,HTML, SQL, XML, JSON, HTTP, 随便就可以列一大堆。
文字块的引入,减轻了多行字符串的编码压力,提高了代码的可读性,进而使得代码更容易维护。
怎么使用文字块?
文字块使用三个双引号来界定文字内容。需要注意的是,声明起始界定符这一行,界定符后只允许空格和换行符。文字内容必须从下一行开始。下面的声明和定义是不合语法的,编译器会检查报错。
结束界定符要紧随着文字内容结束。 上面的例子中,字符串的最后一个字符是换行符。 而下面的这个例子中,字符串的最后一个字符就不是换行符了。
由于使用了三个双引号作为界定符,文字内容可以直接使用双引号,不再需要使用转义字符。
下面显示的上面这个例子的运行结果。从这个结果我们可以看出,输出直接显示了文字内容的格式,包括换行符。 但是,对比于代码,每一行的文字开头都被切除了八个空格。
Java怎么处理文字块?
像普通字符串一样,文字块是字符串的一种常量表达式。不同于常规字符串的是,在编译期,文字块要顺序通过如下三个不同的编译步骤:
为了降低不同平台间换行符的表达差异,编译器把文字内容里的换行符统一转换成LF(\u000A);
删除文字内容里不必要空格,包括文字内容和结束界定符共有的前导空格或者缩进,以及所有的尾部空格;
处理转义字符。
为了说明文字块的编译处理,下面的三个例子,我们使用小数点号‘.’表示要删除的前导空格,使用叹号‘!’表示要删除的尾部空格。
段落该怎么表达?
我们知道,编码规范一般都限定每一行的字节数 ,通常是80个或者120个字节。可是一个段落通常要超出这个限制。文字块里的换行符要保留,编码规范要遵守,该如何表达段落或者一长行呢?
文字块引入了一个新的转义字符,'\',行连接符。 比如,下面的例子中行连接符的使用,就把"Hello World!"连接在一行里了。
连接后的字符,是”HelloWorld“还是”Hello World“?两个单词之间还有空格吗?还记得我们前面说过的编译器处理顺序吗?空格处理先于转义字符处理。因此,行连接符前的空格不算尾部空格,因此会得到保留。
尾部空格可以回来吗?
文字块里的尾部空格在编译期会被删除。 一般情况下,尾部空格没有什么实质性的作用。但是,万一需要尾部空格,它们还可以回来吗?文字块还引入了另外一个新的转义字符,'\s',空格转义符。空格转义符表示一个空格。由于我们前面说过的文字块的编译器处理顺序,空格转义符之前的空格也被保留。
比如下面的例子中,字符串的前两行就包含尾部空格。
文字块是字符串
需要注意的是,文字块定义的是字符串。既然是字符串,就可以使用字符串的API和对应的操作。
比如,普通字符串和文字块可以混合使用:
比如,调用String的方法:
或者,使用嵌入式表达式:
最后,一定要理解下面两点:
文字块是在编译器处理的一种字符串常量表达式
文字块的处理要顺序通过三个编译步骤。
理解了上面两点,文字块的很多概念就清楚了,用法也就清楚了。
好的,今天我们就聊到这儿。
版权声明: 本文为 InfoQ 作者【范学雷】的原创文章。
原文链接:【http://xie.infoq.cn/article/58df026202aa67f7ef24907fc】。未经作者许可,禁止转载。
评论