Logger.getLogger(class_name.class.getName())导致NullPointerException

时间:2012-08-31 21:02:02

标签: java logging static

问题是Logger未使用Logger.getLogger(class_name.class.getName())方法初始化。 你可以看到下面的代码。我标记了导致异常的行。 我必须注意,我尝试过没有静态setLevel阻止。

// File that contains logger
public class Experience {

private final static Experience INSTANCE = new Experience(); 
private final static Logger LOGGER = Logger.getLogger(Experience.class.getName());

private MainFrame main_frame;

static {
    LOGGER.setLevel(Level.SEVERE);
    }

public static Experience getInstance()
    {
    return INSTANCE;
    }

private Experience()
    {
    try
        {
        FileHandler fh = new FileHandler(System.getProperty("user.dir") + "/log.txt");
        fh.setFormatter(new XPLogFormatter());
        LOGGER.addHandler(fh); // NULLPOINTEREXCEPION HERE
        }
    catch (Exception e)
        {
        e.printStackTrace();
        }
    }
}


// Just a loader
public class Loader
{
public static void main(String args[])
    {
    JFrame.setDefaultLookAndFeelDecorated(true);

    SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
                {
                MainFrame main_frame = new MainFrame();
                }
        });
    }
}


// Stripped down version of main frame
public class MainFrame extends JFrame
{
private Experience XP;

public MainFrame()
    {
    super();
    XP = Experience.getInstance(this);
    }
}


// Modified formatter
public class XPLogFormatter extends Formatter
{
@Override
public String format(LogRecord record)
    {
    StringBuffer buf = new StringBuffer(1000);
    buf.append(formatMessage(record));
    return buf.toString();
    }
}

您能否告诉我究竟是什么导致了这个错误?

2 个答案:

答案 0 :(得分:8)

问题是这两个静态变量初始值设定项是按文本顺序执行的:

private final static Experience INSTANCE = new Experience(); 
public final static Logger LOGGER = Logger.getLogger(Experience.class.getName());

所以当第一行调用构造函数时,包括:

LOGGER.addHandler(fh);

... LOGGER仍为空。

最简单的修复只是颠倒声明的顺序......但另一个更清晰的替代方法是在静态初始化器中完成所有操作:

private final static Experience INSTANCE;
public final static Logger LOGGER;

static {
    LOGGER = Logger.getLogger(Experience.class.getName());
    LOGGER.setLevel(Level.SEVERE);
    INSTANCE = new Experience();
}

(出于兴趣,您真的希望记录器公开吗?)

答案 1 :(得分:0)

因为您从未定义过名为“Experience”的Logger。当您调用getLogger(String)时,它会查找具有该名称的已定义记录器。尝试使用Logger.getLogger(Experience.class),它可以让你获得体验的记录器