New Java Feature - Text Blocks
概述
- JDK 15
- 文字块 - 一个由多行文字构成的字符串
复杂字符串
需要处理 - 文本对齐、换行字符、连接符以及双引号的转义字符串 - 不美观 + 不简约 + 不自然
1 | String stringBlock = |
所见即所得的文字块
- 文字块是一个由多行文件构成的字符串
- 文字块使用新的形式,尝试消除换行符、连接符、转义字符的影响
- 使得文字对齐和必要的占位符更加清晰,从而简化多行文字字符串的表达
- 换行符
\n
没有出现在文字块这个 - 连字符
+
没有出现在文字块这个 - 双引号没有使用转义字符
\
与 Python 类似
- 文字块由零个或多个内容字符组成
- 从开始分隔符开始,到结束分隔符结束 -
"""
- 开始分隔符由
"""
开始,后面跟着零个或多个空格,以及行结束符组成的序列- 开始分隔符必须单独成行,前面的
"""
以及后面的空格和换行符都属于开始分隔符 - 因此,一个文字块至少有两行代码
- 即使是一个空字符串,结束分隔符也不能和开始分隔符放在同一行代码里
- 开始分隔符必须单独成行,前面的
- 结束分隔符由
"""
组成的序列
- 开始分隔符由
1 | jshell> String s = """"""; |
结束分隔符只有一个由
"""
组成的序列,在这之前的字符,包括换行符,都属于文字块的有效内容
1 | jshell> String s = """ |
- 由于文字块不再需要特殊字符,几乎可以直接拷贝粘贴看到的文字,不再需要特殊处理
- 在代码中看到的文字块的样子,就是其实际要表达的样子 - 所见即所得
文字块的编译过程
为了代码整洁而使用的缩进空格并没有出现在打印的结果里 - 文本块的内容并没有计入缩进空格
1 | Here is the text block: |
与传统字符串一样,文字块是字符串的一种常量表达式
不同于传统字符串,在编译期间,文字块要顺序通过三个不同的编译步骤
- 为了降低不同平台换行符的表达差异
- 编译器把文字内容里的换行符统一转换成 LF -
\u000A
- 编译器把文字内容里的换行符统一转换成 LF -
- 为了能够处理 Java 源代码里的缩进空格
- 要删除所有文字内容行和结束分隔符共享的前导空格,以及所有文字内容行的尾部空格
- 最后处理转义字符
- 开发人员编写的转义序列不会在第一步和第二步被修改或删除
- 使用传统方式声明的字符串和使用文字块声明的字符串,它们的内容是一样的,并且指向同一个对象
- 文字块是在编译期处理的,并且在编译期被转换成常量字符串,然后被当作常规字符串了
- 如果文字块代表的内容,和传统字符串代表的内容是一样的
- 那么这两个常量字符串变量指向同一个内存地址,代表同一个对象
- 虽然表达形式不同,但文字块就是字符串 - 能够使用字符串支持的各种 API 和操作方法
混合使用
文字块可以调用字符串 String 的 API
1 | int stringSize = |
使用嵌入式的表达式
巧妙的结束分隔符
删除共享的前导空格 - 通过合理地安排共享的前导空格,可以实现文字的编排和缩进
.
表示编译期要删除的前导空格,!
表示编译期要删除的尾部空格
Case 1
把结束分隔符单独放在一行,和文本内容左边对齐
此时,共享的前导空格就是文本内容本身共享的前导空格,结束分隔符仅仅用来结束文字块
1 | // There are 8 leading white spaces in common |
Case 2
把结束分隔符单独放一行,但放在比文本内容更靠左的位置
此时,结束分隔符除了用来结束文字块之外,还参与界定共享的前导空格
1 | // There are 4 leading white spaces in common |
Case 3
把结束分隔符单独放一行,但放在比文件内容左对齐位置的右侧
此时,结束分隔符的左侧,除了共享的前导空格之外,还有多余的空格
这些多余的空格,本质上是文字内容行的尾部空格,它们会在编译期被删除掉
1 | // There are 8 leading white spaces in common |
保留尾部空格
- 为了能够支持尾部附带的空格,文字块引入了另一个新的转义字符 -
\s
表示一个空格 - 空格转义符不会在文字块的编译期被删除,因此空格转义符之前的空格也能被保留 - 每行使用一个
\s
即可
前两行保留尾部空格
1 | // There are 8 leading white spaces in common |
长段落
- 编码规范一般都限定每一行的字节数 - 80/120 - 一个文本的长段落通常要超出这个限制
- 文字块引入了新的转义字符 - 行终止符 - 换行转义符
- 如果换行转义符出现在一个行的结束位置,那么这一行的换行会被取缔
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.