java.util.logging.LogManager.getLogger() 返回 null

phi*_*-de 6 java java.util.logging

我遇到了一个真正让我感到困惑的问题。我想用 JUL 日志(JDK 日志)尝试一些东西。我从以下简单程序开始:

package biz.ple;

import java.util.logging.LogManager;
import java.util.logging.Logger;

public class Application {

    public static void main(String[] args)
    {
        Logger logA = LogManager.getLogManager().getLogger("LoggerA");
        Logger logB = LogManager.getLogManager().getLogger("LoggerB");
        if (logA == null) {
            System.out.println("LoggerA is null!");
        }
        if (logB == null) {
            System.out.println("LoggerB is null!");
        }

        String normalMsg = "Message without cookie prefix.";
        String cookieMsg = "[Cookie] Message with a cookie prefix.";

        logA.info(normalMsg);
        logA.info(cookieMsg);
        logB.info(normalMsg);
        logB.info(cookieMsg);
    }
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,记录器 logA 和 logB始终为空。我在文档中读到应用程序没有强引用的记录器我随时都会被 GC,但在我看来变量 logA 和 logB 确实是强引用,不是吗?

我真的不明白这一点,希望得到任何帮助。

Ric*_*gle 7

我的理解是,这只会获得现有的记录器,而不是创建一个具有该名称的新记录器。要创建一个新的记录器,您需要使用 staticLogger.getLogger("myLogger");命令

public static void main(String[] args){
    Logger log=Logger.getLogger("myLogger");
    
    Logger logA = LogManager.getLogManager().getLogger("myLogger"); //exists
    Logger logB = LogManager.getLogManager().getLogger("nonExistantLogger"); //is null
    
}
Run Code Online (Sandbox Code Playgroud)

Logger.getLogger("myLogger") javadoc:

为命名子系统查找或创建记录器。如果已经使用给定名称创建了记录器,则返回该记录器。否则会创建一个新的记录器。

如果创建了新的记录器,其日志级别将根据 LogManager 配置进行配置,并且还将配置为将日志输出发送到其父级的处理程序。它将在 LogManager 全局命名空间中注册

注意:LogManager 可能只保留对新创建的 Logger 的弱引用。重要的是要了解,如果没有对 Logger 的强引用,则之前创建的具有给定名称的 Logger 可能会在任何时候被垃圾回收。特别是,这意味着如果在别处没有对名为“MyLogger”的 Logger 的强引用,像 getLogger("MyLogger").log(...) 这样的两个背靠背调用可能会使用名为“MyLogger”的不同 Logger 对象在程序中。

LogManager.getLogManager().getLogger("myLogger") javadoc

方法找到一个名为记录。

请注意,由于不受信任的代码可能会创建具有任意名称的记录器,因此不应依赖此方法来查找用于安全敏感日志记录的记录器。同样重要的是要注意,如果没有对 Logger 的强引用,与 String 名称关联的 Logger 可能会随时被垃圾收集。此方法的调用者必须检查返回值是否为 null,以便正确处理 Logger 已被垃圾收集的情况。