SLF4J 使用 {} 占位符实现懒加载日志格式化,避免字符串拼接和提前 toString();支持 null 安全、自动 toString()(仅启用时触发)、异常作为独立参数记录。

Java 日志中用 {} 作为占位符,是 SLF4J(最常用日志门面)的标准写法,核心原则是:**不拼接字符串、不提前调用 toString()、让日志框架在真正需要时才格式化**。这样能避免无谓的性能开销和潜在的空指针异常。
占位符的基本写法
SLF4J 的 logger.debug("msg {}", arg) 会自动将 arg 替换到第一个 {};多个参数按顺序填充:
logger.info("User {} logged in from {}", userId, ip);logger.error("Failed to process order {}, cause: {}", orderId, e.getMessage());
注意:占位符数量必须与参数个数一致,否则多出的参数被忽略,缺少则抛 IllegalArgumentException。
处理 null 和复杂对象
SLF4J 对 null 安全:占位符遇到 null 会显示字符串 "null",不会报错:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
立即学习“Java免费学习笔记(深入)”;
-
logger.debug("Name: {}, Age: {}", name, age);—— 即使name == null也安全 - 对象会自动调用
toString(),但仅在日志级别启用且实际输出时才触发(懒加载),避免无效 toString 开销
避免常见错误写法
以下写法都违背占位符设计初衷:
-
❌ 错误:字符串拼接 ——
logger.info("User " + user.getName() + " logged in");
→ 拼接总发生,无论日志是否开启,浪费 CPU 和内存 -
❌ 错误:提前 toString() ——
logger.debug("Order: " + order.toString());
→ 即使 debug 关闭,order.toString()仍被执行 -
❌ 错误:混用 + 和 {} ——
logger.info("Error: " + msg + " at {}", line);
→ 前半段已拼接,失去占位符优势
特殊场景:可变参数和异常
SLF4J 支持最后一个参数为 Throwable,它不会被当作占位符,而是作为独立异常堆栈记录:
-
logger.error("Failed to save user {}", userId, e);
→e是异常,日志中会打印消息 + 占位符替换结果 + 完整堆栈 - 多个占位符后不能跟异常以外的额外参数,否则异常会被当成普通参数处理,丢失堆栈


















