本文目录导读:

是的,Java 13 引入、并在 Java 15 正式转正的文本块(Text Blocks)功能,确实让多行字符串的处理变得更加优雅、可读性更高。
文本块解决了传统 Java 字符串在处理 HTML、JSON、SQL、多行消息等场景时的可读性灾难。
下面我们通过几个对比,看看它为什么“更优雅”。
告别转义和拼接地狱
传统写法(非常痛苦):
// 一个简单的 HTML 片段
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world!</p>\n" +
" </body>\n" +
"</html>";
// 或者用转义序列(更难看)
String json = "{\n" +
" \"name\": \"Alice\",\n" +
" \"age\": 30,\n" +
" \"city\": \"New York\"\n" +
"}";
使用文本块(清爽直观):
String html = """
<html>
<body>
<p>Hello, world!</p>
</body>
</html>
""";
String json = """
{
"name": "Alice",
"age": 30,
"city": "New York"
}
""";
你看,代码就是文档本身的样子,不再需要数着 \n 去对齐,也不再需要写无数个 号。
自动去除缩进公共前缀,代码依旧整洁
在代码中,我们通常会把文本块缩进到与周围代码平齐的位置,文本块会自动识别并剥离所有行共有的缩进前缀,既保持了源代码的美观,又不会在生成的字符串中产生多余的空白。
public class Demo {
public void show() {
String message = """
Hello,
This is a multi-line
string.
""";
// 实际输出:
// Hello,
// This is a multi-line
// string.
}
}
- 代码里的缩进是
16个空格(或4个制表符)。 - 文本块自动计算公共缩进(16个空格),然后剔除,最终字符串从第二行开始就没有缩进了。
如果你确实需要保留缩进,可以使用
indent()方法或者配合\s(强制空格)来控制。
灵活的转义:忽略换行或保留尾部空格
文本块并不是不能使用转义,它只是让常用场景变得简单,同时提供了精确控制的能力。
-
行尾续行符:当一行末尾有 时,表示忽略这一行末尾的换行符,常用于连接很长的单行字符串。
String veryLongSql = """ SELECT id, name, email, address, phone \ FROM users \ WHERE status = 'active' \ ORDER BY created_at DESC """; // 实际是一行:SELECT id, name, email, address, phone FROM users WHERE status = 'active' ORDER BY created_at DESC -
\s(Java 14+):在行尾显式插入一个空格,防止文本块自动修剪行尾的空白。
性能上无额外开销
文本块是编译时的语法糖,编译器会在 .class 文件中将文本块解析为传统的 CONSTANT_String_info 常量,这意味着:
- 运行时和传统字符串完全相同。
- 同样支持字符串常量池(
String Pool)的复用。 - 拼接性能反而比传统的 拼接更好(因为编译器能一次性处理好)。
对比其他语言的文本块
虽然 Python 有 、JavaScript 有 模板字面量 ,但 Java 的文本块有自己的严谨性:
- 严格的三引号规则,不会像 Python 那样容易误判空字符串。
- 自动缩进剥离 + 可选的 和
\s转义控制,比较灵活。 - 编译时优化,无需运行时解析。
适用场景
| 场景 | 传统写法 | 文本块 |
|---|---|---|
| HTML / XML 模板 | 大量 和引号,极易出错 | 直接写原始格式,清晰 |
| JSON 字符串(测试数据、模拟响应) | 转义双引号,行尾加 \n |
直接写标准 JSON |
| SQL 语句(多行查询) | 每行写一个 和换行 | 直接写 SQL 原样 |
| 多行消息、日志格式、正则表达式 | 转义复杂 | 更清晰易读 |
需要注意的小地方
-
行尾空白会被自动删除,如果你想保留(Markdown 代码块中的行尾空格),需要使用
\s。 -
每行最后一个字符必须是换行,意味着文本块生成的字符串总是以换行符结尾,如果你不想要最后一个换行,可以使用
stripTrailing()或者把 放在最后一行内容之后。 -
如果你需要拼接变量,文本块本身不支持插值(像 JS 的 ),你需要配合
String.format()或str.formatted()使用。String name = "Bob"; String greeting = """ Hello, %s! Welcome to Java Text Blocks. """.formatted(name);
更优雅了吗?
是的。
文本块不是革命性的特性,但它解决了一个长期困扰 Java 开发者的“小痛点”,它带来的最大价值是可读性和维护性:
- 视觉对齐:代码即文档,一眼就能看出字符串的本来面貌。
- 减少错误:无需再手动拼接和转义,降低了出错概率。
- 编译高效:零运行时开销,只是写代码时更舒服了。
如果你还在写大段的 "line1\n" + "line2\n" 这种代码,建议尽快改用文本块,你会觉得写字符串突然变得舒心不少。