你还在用 `+ “\\n“` 拼多行字符串吗?Java 的文本块都已经能让代码“像人写的”了!

发布时间:2026/6/10 20:16:48

你还在用 `+ “\\n“` 拼多行字符串吗?Java 的文本块都已经能让代码“像人写的”了! 你好欢迎来到我的博客我是【菜鸟不学编程】我是一个正在奋斗中的职场码农步入职场多年正在从“小码农”慢慢成长为有深度、有思考的技术人。在这条不断进阶的路上我决定记录下自己的学习与成长过程也希望通过博客结识更多志同道合的朋友。️ 主要方向包括 Java 基础、Spring 全家桶、数据库优化、项目实战等也会分享一些踩坑经历与面试复盘希望能为还在迷茫中的你提供一些参考。 我相信写作是一种思考的过程分享是一种进步的方式。如果你和我一样热爱技术、热爱成长欢迎关注我一起交流进步全文目录I. 文本块语法 多行字符串 1基本用法三引号包起来2起始行的“小规矩”II. 转义与缩进自动处理空格但别误会它“会读心”1缩进裁剪它会找“最小公共缩进”2想控制末尾换行用 \行尾反斜杠3需要在行尾保留空格用 \sIII. 格式化String::formatted 方法终于不用满屏 了1示例生成一段 JSON2小心“格式化注入”别在高风险输入上裸奔IV. 与传统字符串比较可读性提升不是“语法糖”是“维护成本下降”1传统写法拼接 转义 换行符2文本块写法结构就是结构V. HTML/JSON 应用嵌入多行文本最常见、最值得1SQL别再在字符串里“逃逸人生”2JSON结构清晰编辑成本低3HTML用于邮件模板/报表渲染VI. 项目生成报告的文本块使用一个“像工程”的小报表1定义一个简单的数据模型2用文本块生成 Markdown 报告3用文本块生成 HTML 报告简单版4跑一个 demo生成两份报告字符串小结文本块不是“更短”是“更不容易写错” 写在最后I. 文本块语法 多行字符串 文本块最直观的优点就是多行就是多行不需要你手动写换行符。1基本用法三引号包起来Stringsql SELECT id, name, created_at FROM users WHERE status ACTIVE ORDER BY created_at DESC ;你看字符串里有换行、缩进代码也有换行、缩进——读起来像你脑子里想的样子。2起始行的“小规矩”开始的后面通常换行更清晰结束的所在位置会影响缩进裁剪下一节讲II. 转义与缩进自动处理空格但别误会它“会读心”文本块有两个“真香点”自动处理缩进indentation stripping减少转义需求1缩进裁剪它会找“最小公共缩进”看这个例子Strings line1 line2 line3 ;System.out.println(s);输出会保留相对缩进但会裁掉“所有行共有的最小缩进”。这意味着你可以为了让代码排版好看而缩进但最终字符串不会多出那些“为了对齐而产生的多余空格”。重点它保留相对缩进不是把所有行都左对齐。2想控制末尾换行用\行尾反斜杠文本块默认会包含结尾换行多数时候是你想要的。但如果你不想要最后那个换行StringnoTrailingNewline hello world\;这个\会把最后的换行“吃掉”。第一次见的人一般会“啊”一下正常3需要在行尾保留空格用\s有时候你想保留行尾空格例如 Markdown 对齐、某些固定格式输出文本块会帮你裁剪得太“干净”。这时你可以显式保留StringkeepSpace a\s b\s ;III. 格式化String::formatted方法终于不用满屏了文本块和formatted()简直是天生一对你写一个模板再把变量填进去代码立刻从“拼接现场”变成“模板渲染”。1示例生成一段 JSONStringnameOphelia;intscore97;Stringjson { name: %s, score: %d, passed: %b } .formatted(name,score,score60);System.out.println(json);你会发现它比String.format(...)更顺手的地方在于模板字符串就在那儿你一眼能看到结构不用在参数列表里找半天。当然它底层还是走 format 语义格式符%s/%d/%f那些规则都一样。2小心“格式化注入”别在高风险输入上裸奔如果用户输入里可能包含%在某些场景会造成格式化异常或输出混乱。高风险场景请先转义或用更安全的模板渲染方式尤其是日志/SQL/命令行这类。IV. 与传统字符串比较可读性提升不是“语法糖”是“维护成本下降”我们来对比一下经典的“字符串地狱”。1传统写法拼接 转义 换行符Stringhtmlhtml\n body\n h1Report/h1\n /body\n/html\n;读起来像在数\n写起来像在搬砖还容易漏掉引号。2文本块写法结构就是结构Stringhtml html body h1Report/h1 /body /html ;维护体验差别非常大改一行 HTML不会牵动 10 行拼接diff 更干净代码审查也更容易少了很多“我是不是漏了个”的低级错误所以它不是仅仅“少写几个字符”而是降低未来维护者包括你自己脑内负担。V. HTML/JSON 应用嵌入多行文本最常见、最值得文本块最舒服的用途就是放这些“结构化文本”1SQL别再在字符串里“逃逸人生”Stringsql SELECT id, name FROM users WHERE age %d ORDER BY name .formatted(18);2JSON结构清晰编辑成本低Stringpayload { event: login, userId: %s, timestamp: %s } .formatted(u-42,java.time.Instant.now());3HTML用于邮件模板/报表渲染Stringpage div classcard h2%s/h2 p%s/p /div .formatted(Weekly Report,All systems nominal.);但我得提醒一句如果你在做复杂 HTML 模板文本块只是“字符串更好写”它不是模板引擎。复杂场景建议用真正的模板方案比如 Thymeleaf/Freemarker 等别硬撑。VI. 项目生成报告的文本块使用一个“像工程”的小报表我们做个小项目生成一份“运行报告”同时输出Markdown和HTML两种格式。为什么是这两种因为它们最能体现文本块的价值结构化、多行、可读。1定义一个简单的数据模型importjava.time.Instant;importjava.util.List;publicrecordReport(Stringtitle,InstantgeneratedAt,ListItemitems){publicrecordItem(Stringname,Stringstatus,longlatencyMs){}}2用文本块生成 Markdown 报告importjava.util.stream.Collectors;publicclassReportRenderer{publicstaticStringtoMarkdown(Reportr){Stringrowsr.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 报告简单版importjava.util.stream.Collectors;publicclassHtmlReportRenderer{publicstaticStringtoHtml(Reportr){Stringrowsr.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 langen head meta charsetutf-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 pbGenerated At:/b %s/p table thead trthName/ththStatus/ththLatency/th/tr /thead tbody %s /tbody /table /body /html .formatted(escape(r.title()),escape(r.title()),r.generatedAt(),rows);}privatestaticStringescape(Strings){if(snull)return;returns.replace(,amp;).replace(,lt;).replace(,gt;).replace(\,quot;);}}注意一个小细节CSS 里有100%在formatted()模板中%是格式符起始所以要写100%%。这类“百分号小坑”在模板里很常见别踩一次才记住。4跑一个 demo生成两份报告字符串importjava.time.Instant;importjava.util.List;publicclassReportDemo{publicstaticvoidmain(String[]args){ReportreportnewReport(Service Health Report,Instant.now(),List.of(newReport.Item(UserService,OK,23),newReport.Item(OrderService,WARN,187),newReport.Item(PaymentService,FAIL,0)));StringmdReportRenderer.toMarkdown(report);StringhtmlHtmlReportRenderer.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 本文原创转载请注明出处。

相关新闻