👋 你好,欢迎来到我的博客!我是【菜鸟不学编程】
我是一个正在奋斗中的职场码农,步入职场多年,正在从“小码农”慢慢成长为有深度、有思考的技术人。在这条不断进阶的路上,我决定记录下自己的学习与成长过程,也希望通过博客结识更多志同道合的朋友。
🛠️ 主要方向包括 Java 基础、Spring 全家桶、数据库优化、项目实战等,也会分享一些踩坑经历与面试复盘,希望能为还在迷茫中的你提供一些参考。
💡 我相信:写作是一种思考的过程,分享是一种进步的方式。
如果你和我一样热爱技术、热爱成长,欢迎关注我,一起交流进步!
全文目录:
I. 文本块语法:""" 多行字符串 """
文本块最直观的优点就是:多行就是多行,不需要你手动写换行符。
1)基本用法:三引号包起来
String sql = """
SELECT id, name, created_at
FROM users
WHERE status = 'ACTIVE'
ORDER BY created_at DESC
""";
你看,字符串里有换行、缩进,代码也有换行、缩进——读起来像你脑子里想的样子。
2)起始行的“小规矩”
- 开始的
"""后面通常换行(更清晰) - 结束的
"""所在位置会影响缩进裁剪(下一节讲)
II. 转义与缩进:自动处理空格(但别误会它“会读心”)
文本块有两个“真香点”:
- 自动处理缩进(indentation stripping)
- 减少转义需求
1)缩进裁剪:它会找“最小公共缩进”
看这个例子:
String s = """
line1
line2
line3
""";
System.out.println(s);
输出会保留相对缩进,但会裁掉“所有行共有的最小缩进”。
这意味着:你可以为了让代码排版好看而缩进,但最终字符串不会多出那些“为了对齐而产生的多余空格”。
重点:它保留相对缩进,不是把所有行都左对齐。
2)想控制末尾换行?用 \(行尾反斜杠)
文本块默认会包含结尾换行(多数时候是你想要的)。
但如果你不想要最后那个换行:
String noTrailingNewline = """
hello
world\
""";
这个 \ 会把最后的换行“吃掉”。
(第一次见的人一般会“啊?”一下,正常😄)
3)需要在行尾保留空格?用 \s
有时候你想保留行尾空格(例如 Markdown 对齐、某些固定格式输出),文本块会帮你裁剪得太“干净”。这时你可以显式保留:
String keepSpace = """
a\s
b\s
""";
III. 格式化:String::formatted 方法(终于不用满屏 + 了)
文本块和 formatted() 简直是天生一对:
你写一个模板,再把变量填进去,代码立刻从“拼接现场”变成“模板渲染”。
1)示例:生成一段 JSON
String name = "Ophelia";
int score = 97;
String json = """
{
"name": "%s",
"score": %d,
"passed": %b
}
""".formatted(name, score, score >= 60);
System.out.println(json);
你会发现它比 String.format(...) 更顺手的地方在于:
模板字符串就在那儿,你一眼能看到结构,不用在参数列表里找半天。
当然,它底层还是走 format 语义,格式符
%s/%d/%f那些规则都一样。
2)小心“格式化注入”(别在高风险输入上裸奔)
如果用户输入里可能包含 %,在某些场景会造成格式化异常或输出混乱。
高风险场景请先转义或用更安全的模板渲染方式(尤其是日志/SQL/命令行这类)。
IV. 与传统字符串比较:可读性提升(不是“语法糖”,是“维护成本下降”)
我们来对比一下经典的“字符串地狱”。
1)传统写法:拼接 + 转义 + 换行符
String html =
"<html>\n" +
" <body>\n" +
" <h1>Report</h1>\n" +
" </body>\n" +
"</html>\n";
读起来像在数 \n,写起来像在搬砖,还容易漏掉引号。
2)文本块写法:结构就是结构
String html = """
<html>
<body>
<h1>Report</h1>
</body>
</html>
""";
维护体验差别非常大:
- 改一行 HTML,不会牵动 10 行拼接
- diff 更干净,代码审查也更容易
- 少了很多“我是不是漏了个
+”的低级错误
所以它不是仅仅“少写几个字符”,而是:降低未来维护者(包括你自己)脑内负担。
V. HTML/JSON 应用:嵌入多行文本(最常见、最值得)
文本块最舒服的用途就是放这些“结构化文本”:
1)SQL:别再在字符串里“逃逸人生”
String sql = """
SELECT id, name
FROM users
WHERE age >= %d
ORDER BY name
""".formatted(18);
2)JSON:结构清晰,编辑成本低
String payload = """
{
"event": "login",
"userId": "%s",
"timestamp": "%s"
}
""".formatted("u-42", java.time.Instant.now());
3)HTML:用于邮件模板/报表渲染
String page = """
<div class="card">
<h2>%s</h2>
<p>%s</p>
</div>
""".formatted("Weekly Report", "All systems nominal.");
但我得提醒一句:如果你在做复杂 HTML 模板,文本块只是“字符串更好写”,它不是模板引擎。复杂场景建议用真正的模板方案(比如 Thymeleaf/Freemarker 等),别硬撑🙂。
VI. 项目:生成报告的文本块使用(一个“像工程”的小报表)
我们做个小项目:生成一份“运行报告”,同时输出 Markdown 和 HTML 两种格式。
为什么是这两种?因为它们最能体现文本块的价值:结构化、多行、可读。
1)定义一个简单的数据模型
import java.time.Instant;
import java.util.List;
public record Report(
String title,
Instant generatedAt,
List<Item> items
) {
public record Item(String name, String status, long latencyMs) {}
}
2)用文本块生成 Markdown 报告
import java.util.stream.Collectors;
public class ReportRenderer {
public static String toMarkdown(Report r) {
String rows = r.items().stream()
.map(i -> "| %s | %s | %dms |".formatted(i.name(), i.status(), i.latencyMs()))
.collect(Collectors.joining("\n"));
return """
# %s
- Generated At: %s
- Total Items: %d
| Name | Status | Latency |
| ---|--------|---------|
%s
> Note: Latency is measured at client side.
""".formatted(
r.title(),
r.generatedAt(),
r.items().size(),
rows
);
}
}
你会发现:Markdown 的“表格块”在文本块里写起来特别顺,不会被 \n 折磨。
3)用文本块生成 HTML 报告(简单版)
import java.util.stream.Collectors;
public class HtmlReportRenderer {
public static String toHtml(Report r) {
String rows = r.items().stream()
.map(i -> """
<tr>
<td>%s</td>
<td>%s</td>
<td>%d ms</td>
</tr>
""".formatted(escape(i.name()), escape(i.status()), i.latencyMs()))
.collect(Collectors.joining("\n"));
return """
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>%s</title>
<style>
body { font-family: Arial, sans-serif; margin: 24px; }
table { border-collapse: collapse; width: 100%%; }
th, td { border: 1px solid #ddd; padding: 8px; }
th { text-align: left; }
</style>
</head>
<body>
<h1>%s</h1>
<p><b>Generated At:</b> %s</p>
<table>
<thead>
<tr><th>Name</th><th>Status</th><th>Latency</th></tr>
</thead>
<tbody>
%s
</tbody>
</table>
</body>
</html>
""".formatted(
escape(r.title()),
escape(r.title()),
r.generatedAt(),
rows
);
}
private static String escape(String s) {
if (s == null) return "";
return s.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """);
}
}
注意一个小细节:CSS 里有 100%,在 formatted() 模板中 % 是格式符起始,所以要写 100%%。
这类“百分号小坑”在模板里很常见,别踩一次才记住😅。
4)跑一个 demo(生成两份报告字符串)
import java.time.Instant;
import java.util.List;
public class ReportDemo {
public static void main(String[] args) {
Report report = new Report(
"Service Health Report",
Instant.now(),
List.of(
new Report.Item("UserService", "OK", 23),
new Report.Item("OrderService", "WARN", 187),
new Report.Item("PaymentService", "FAIL", 0)
)
);
String md = ReportRenderer.toMarkdown(report);
String html = HtmlReportRenderer.toHtml(report);
System.out.println(md);
System.out.println("------");
System.out.println(html.substring(0, Math.min(400, html.length())) + "...");
}
}
小结:文本块不是“更短”,是“更不容易写错”
Java 文本块最值钱的地方不是省了多少字符,而是:
- 结构可读:HTML/JSON/SQL 这类文本“长得像它本来的样子”
- 少转义:减少
\n\t\"这种视觉噪音 - 更好维护:代码 diff 更干净,评审更轻松
- 搭配 formatted:模板化输出更自然
最后我想用一句反问收尾(你应该已经习惯我这种嘴欠式结尾了😄):
你写的多行字符串,是在表达“内容”,还是在表达“转义规则”?
如果答案是后者——那文本块真的该用起来了🙂。
📝 写在最后
如果你觉得这篇文章对你有帮助,或者有任何想法、建议,欢迎在评论区留言交流!你的每一个点赞 👍、收藏 ⭐、关注 ❤️,都是我持续更新的最大动力!
我是一个在代码世界里不断摸索的小码农,愿我们都能在成长的路上越走越远,越学越强!
感谢你的阅读,我们下篇文章再见~👋
✍️ 作者:某个被流“治愈”过的 Java 老兵
📅 日期:2025-08-25
🧵 本文原创,转载请注明出处。

588

被折叠的 条评论
为什么被折叠?



