string.format输出规范日志需确保变量类型匹配、占位符清晰、避免空指针和格式错误;%s适用于任意对象,%d仅限整型,%f用于浮点数并控制精度,%b输出布尔值;需提前判空并用objects.tostring()防护,长文本应截断或脱敏,slf4j的{}占位符更优。

用 String.format 输出规范日志,关键在于**变量类型匹配、占位符清晰、避免空指针和格式错误**。直接拼接字符串易出错,而 String.format 提供类型安全与可读性,适合结构化日志场景。
正确使用占位符对应变量类型
不同数据类型需匹配对应格式符,否则运行时报 IllegalFormatConversionException:
-
%s:任意对象(自动调用toString()),最常用,适合字符串、数字、枚举等 -
%d:仅整型(int,long等),不能用于Double或null -
%f:浮点数,注意精度控制,如%.2f保留两位小数 -
%b:布尔值,null也会输出false
示例:
String log = String.format("用户[%s]登录失败,尝试次数:%d,耗时:%.2fms",
username, loginAttempts, responseTime);
提前判空避免 NullPointerException
String.format 对 null 参数处理有限——%s 可接受 null(输出字符串 "null"),但 %d、%f 等会直接抛异常。建议统一做空值防护:
- 用
Objects.toString(obj, "N/A")替代裸obj,防止null导致崩溃或日志歧义 - 对数值型变量,显式转为包装类再判空,或默认兜底值(如
loginAttempts != null ? loginAttempts : 0)
更简洁写法:
String log = String.format("订单[%s]状态更新,金额:%.2f,操作人:%s",
Objects.toString(orderId, "unknown"),
amount != null ? amount : 0.0,
Objects.toString(operator, "-"));
控制日志长度与敏感信息脱敏
长文本(如 JSON、堆栈、URL)直接插入易撑爆日志行或泄露敏感字段。可通过格式符截断或预处理:
-
%.50s:最多输出前 50 个字符,超出部分省略(适合 traceId、requestBody 等) - 对手机号、身份证、token 等,先脱敏再传入,不要依赖格式化完成脱敏
- 避免在格式化中嵌套复杂表达式,保持可读性和调试友好性
例如:
String safeToken = token != null ? token.substring(0, Math.min(8, token.length())) + "..." : "null";
String log = String.format("API 调用,路径:%s,token:%.16s,耗时:%dms",
path, safeToken, duration);
结合 SLF4J 推荐替代方案(补充说明)
虽然 String.format 可用,但主流日志框架如 SLF4J 提供更优的占位符机制({}),支持延迟格式化、避免无用拼接:
- SLF4J 的
logger.info("用户{}操作{},耗时{}ms", user, action, time)更高效,且不因参数为null报错 - 若必须用
String.format(如写入文件、构造消息体),确保变量已校验、类型明确、长度可控
纯 Java 场景下,String.format 仍可靠,只需守住类型、空值、长度三个边界。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











