String.indent() 在 Java 12+ 中按行拆分字符串(识别 \n、\r\n、\r),对每行首空格增减指定数量,负数时“尽力移除”而非截断,不处理制表符,且兼容空行、全空白行。

String.indent() 在 Java 12+ 中到底做了什么
String.indent() 不是“加空格”那么简单,它会先按行拆分字符串(用 \n、\r\n、\r),对每行开头插入或删除指定数量的空格,再重新拼接。负数参数会尝试移除开头空格(最多删到行首非空字符为止),不是简单截断。
为什么用 indent() 而不是自己写 replaceFirst 或 repeat
手拼前缀容易漏掉换行符边界处理;indent() 自动识别所有标准换行符,且对单行、空行、全空白行有明确定义行为。比如:
"".indent(2) → "" " hello".indent(-4) → "hello" "\n x".indent(1) → "\n x"
- 负缩进时不会抛异常,而是“尽力而为”——这点常被忽略
- 如果某行原始缩进少于要减的数量,该行只清空已有空白,不补
IllegalArgumentException - 它不碰制表符
\t,只处理空格(U+0020)
常见错误:传入负数却没观察到变化
现象:"line1\n line2".indent(-1) 执行后还是原样。原因:每行开头必须**恰好是空格**才能被减;"line1" 行首无空格," line2" 行首只有 2 个空格,减 1 后剩 1 个——看起来“没变”。
- 检查目标行是否真以空格开头(用
charAt(0) == ' '验证) - 用
String.stripIndent()(Java 15+)替代,它按缩进最少的非空行对齐,更适合代码块场景 - 不要对含混合缩进(空格+制表符)的字符串用
indent(),结果不可控
性能和兼容性要注意的点
indent() 是 Java 12 引入的,低版本运行会 NoSuchMethodError;它内部会创建新字符串数组,对超长多行文本(如日志块)有明显 GC 压力。
立即学习“Java免费学习笔记(深入)”;
- Android 开发需注意:仅 API 30+(R)支持,旧设备需降级处理
- 若只是给单行加前缀,用
"prefix" + str更快,indent()的开销不值得 - 在循环里频繁调用?先确认是否真需要逐行动态缩进——多数情况可预计算或改用
StringBuilder拼接
真正麻烦的是混合了缩进策略的场景:比如想让 JSON 字符串按层级缩进,但又得保留用户原始换行意图。indent() 只做机械增减,不理解结构,这时候就得退回到 Jackson/Gson 的 setPrettyPrinting() 之类专用方案。










