该异常表明格式化时精度设置不合法:整数类(%d、%o、%x等)、%b、%c、%h不支持精度;%f、%e、%g、%a、%s支持但精度须≥0(-1除外);修复需检查格式串中“.n”前的转换符并校验精度值。

这个异常直接告诉你:格式化时设的小数位数(precision)不合法。最常见的是给不支持精度的格式符加了小数点,比如用 %d 却写了 %.2d;或者给支持精度的格式符(如 %f)传了负数精度(%.−1f),或精度大到超出整型范围。
哪些格式符根本不允许精度?
整数类转换符一律不接受小数点和精度设置,包括:
-
%d、%o、%x、%X(十进制、八进制、十六进制) -
%b、%c、%s(布尔、字符、字符串) -
%h(哈希码)
一旦对它们使用 .N(如 %.3d),立刻抛 IllegalFormatPrecisionException。注意:%s 虽然支持精度(截取前 N 个字符),但若 N 为负数(除 -1 外),也会触发该异常。
哪些格式符支持精度?怎么用才安全?
只有浮点类和部分通用转换符支持精度,且含义不同:
-
%f、%e、%g、%a:精度表示小数点后位数(%.2f→ 保留两位小数) -
%s:精度表示最多输出的字符数(%.5s→ 最多取前 5 个字符) -
%t时间格式符:部分子转换(如%tc)支持精度,但含义是字段宽度,不是小数位
安全做法是:只对 f/e/g/a/s 使用精度,并确保值 ≥ 0(-1 是唯一允许的负值,表示“无精度限制”,等效于不写)。
怎么快速定位和修复?
看报错堆栈里的格式字符串,重点检查所有带 . 的地方:
- 如果
.后面跟的是数字,往前看紧邻的转换符 —— 是d、x这类?删掉.N - 如果是
f或s,检查那个数字是不是负数(比如−2)或极大(如9999999999)→ 改为非负合理值 - 用
String.format前可先做校验:对每个格式段提取精度部分,判断是否在 [0, Integer.MAX_VALUE] 内
预防比捕获更有效
这个异常属于运行时 unchecked 异常,不强制捕获。但与其写 try-catch,不如从源头避免:
- 固定格式字符串尽量手写,避免拼接出非法格式(如
"%." + precision + "f"中 precision 可能为负) - 动态精度场景下,统一做兜底:
Math.max(0, userProvidedPrecision) - 用
DecimalFormat替代String.format处理金额/浮点数,它对精度更宽容,且错误反馈更明确
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











