Java Formatter 的宽度是“最小总宽”而非固定列宽,字符串不加精度不截断,数字需显式用0标志补零,对齐与填充须组合标志控制。

Java 的 Formatter 确实能模拟 C 的 printf,但默认左对齐、不补零、宽度行为有陷阱
Java 的 Formatter(包括 String.format、System.out.printf)底层就是基于它,语法高度兼容 C 的 printf,但新手常误以为写 ] 就和 C 一样“自动右对齐+空格填充”——实际没错,但遇到负数、字符串、浮点数时表现会偏离直觉。关键在于:对齐方向、填充字符、精度、标志位(如 -、0、+)必须显式组合,不能依赖默认。
%-10s 和 %10s 的区别不只是“减号”,还决定填充位置和是否截断
对字符串:%10s 右对齐、左侧补空格;%-10s 左对齐、右侧补空格;但如果字符串长度超过 10,默认**不截断**,而是照常输出(这点和 C 的 %.10s 不同)。要截断,必须加精度:例如 %.10s 表示最多取前 10 个字符,再配合宽度:%10.10s 才是“占 10 位、超长截断、右对齐”。常见错误是只写 %10s 却期望自动截断,结果字段撑开整个输出。
-
%10s→ 字符串不足 10 字符时左补空格,超长则原样输出 -
%-10s→ 不足时右补空格,超长同样不截断 -
%10.5s→ 先截成最多 5 字符,再右对齐填至总宽 10 -
%.5s→ 无最小宽度,只截断,不补空格
数字输出中 0 标志位只对数值类型生效,且会覆盖空格填充
想让整数用 0 填充而非空格(如 00042),必须同时指定宽度和 0 标志:%05d。但注意:0 标志仅对 d、f、e 等数值转换符有效,对 s 无效;而且一旦用了 0,就**不能再用空格填充**——%05d 和 % 05d(带空格)语义不同,后者空格会被忽略,实际仍是 0 填充。负数时,- 符号占一位,0 填充从符号后开始:例如 %06d 格式化 -42 得到 -00042(共 6 位,含负号)。
-
]→" 42"(3 空格 + 42) -
%05d→"00042" -
%06d格式化-42→"-00042"(不是"00-42") -
%+06d→ 强制显示正号:"+00042"
浮点数的宽度与精度需分开控制,%.2f 不等于 %6.2f
%.2f 只控制小数位数(精度),不设最小总宽度;%6.2f 才表示“总宽至少 6,其中小数占 2 位,整数部分+小数点+小数共占 3 位,剩下由整数位和前导空格/零补足”。例如 3.14159 用 %6.2f 输出为 " 3.14"(2 空格 + 3.14),而 %06.2f 则为 "003.14"。容易被忽略的是:当整数部分很长(如 1234.56),%6.2f 会自动扩展宽度,因为 6 是**最小宽度**,不是固定宽度。
-
%.2f→"3.14",无对齐、无填充 -
%8.2f→" 3.14"(右对齐,总宽 ≥8) -
%-8.2f→"3.14 "(左对齐) -
%08.2f→"00003.14"(注意:整数部分 0 填充,不含小数点)
真正难的不是记住格式语法,而是意识到 Java 的 Formatter 宽度是“最小总宽”,不是固定列宽;截断、补零、对齐、符号控制全靠组合标志,漏一个就出偏差。尤其混用字符串和数字时,别假设它们共享同一套对齐逻辑——s 和 d 对 0 标志的响应完全不同。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











