您的位置:首页 >Java 9平台日志记录器使用详解
发布于2026-04-17 阅读(0)
扫一扫,手机访问
System.getLogger 仅适用于不引入第三方依赖且日志需求极简的场景,如模块化系统内部调试;它不是 Log4j2 或 SLF4J 的替代品,也不支持运行时输出配置,底层绑定由启动时 LoggerFinder 决定。

绝大多数 Java 应用——尤其是还在用 Log4j2、SLF4J + Logback 的项目——完全没必要迁移到 System.getLogger。它不是替代方案,而是 JDK 自带的轻量级门面,定位接近 java.util.logging.Logger,但更抽象、更“只读”。只有当你明确需要不引入第三方依赖、且日志需求极简(比如工具类、启动诊断、模块化系统内部调试),才值得考虑。
System.getLogger 返回的是 Logger 实例,但它的行为完全由 JVM 启动时绑定的 System.LoggerFinder 决定。默认实现(jdk.internal.logger.DefaultLoggerFinder)根本不支持运行时替换底层输出——调用 setLogWriter 或类似方法无效,也不会报错,只是静默忽略。
--add-opens java.base/jdk.internal.logger=ALL-UNNAMED + 自定义 LoggerFinder 子类,并用 -Djdk.logger.finder=your.CustomFinder 指定ServiceLoader 替换(JDK 9–17 中该机制未公开暴露)System.getLogger 输出,基本会失败它不是 JUL 的升级版,也不是封装层;它是并行存在的另一套抽象。JUL 的 Logger 是具体实现类,而 System.getLogger 返回的是接口 System.Logger,JDK 默认把它桥接到 JUL,但这个桥接是单向、不可配置的。
System.getLogger("com.example") 实际拿到的是一个包装了 JUL java.util.logging.Logger 的适配器logging.properties 依然控制它的输出格式和级别,但 System.Logger 接口本身不暴露 setLevel、addHandler 等方法-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager),System.getLogger 可能退化为丢弃所有日志,且无提示模块化(JPMS)环境下的跨模块轻量调试最贴近它的设计意图。比如你写了一个 java.base 之外的平台服务模块,想记录初始化状态,又不想强制依赖 SLF4J ——这时可以用:
ModuleLayer.Controller controller = ModuleLayer.boot().controller();
controller.addModules(Set.of(YourModule.class));
// 在模块静态初始化块中
System.getLogger("YourModule").log(System.Logger.Level.DEBUG, "booted");
但要注意:System.Logger.Level 和 JUL 的 Level 枚举值不一一对应(例如没有 TRACE),且 log() 方法重载少,不支持 lazy lambda 形参(JDK 17 才加 log(Level, Supplier))。
真正容易被忽略的是:它的 isLoggable 判断开销比你想象中高——每次调用都会触发一次 LoggerFinder.getLogger 查找+适配器创建,高频日志场景下可能成为瓶颈。
上一篇:《粉笔教师》课程兑换教程
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9