Java最终静态字段在第一次使用时为空

Java最终静态字段在第一次使用时为空,java,logging,static-initialization,Java,Logging,Static Initialization,有一个类应该将日志存储在本地文件中,该文件被硬编码到程序中 初始化它的逻辑如下所示: import java.util.logging.FileHandler; 导入java.util.logging.Level; 导入java.util.logging.Logger; 导入java.io.IOException; 公共类Util{ 私有静态最终记录器Logger=Logger.getLogger(Util.class.getName()); 私有静态final FileHandler File

有一个类应该将日志存储在本地文件中,该文件被硬编码到程序中

初始化它的逻辑如下所示:

import java.util.logging.FileHandler;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入java.io.IOException;
公共类Util{
私有静态最终记录器Logger=Logger.getLogger(Util.class.getName());
私有静态final FileHandler FileHandler=createFileHandler();
私有静态FileHandler createFileHandler(){
文件处理程序;
试一试{
handler=newfilehandler(“security.log”,0,1,true);
addHandler(filehandler);
}捕获(IOException | SecurityException e){
handler=null;
LOGGER.log(Level.SEVERE,“无法创建安全日志!”);
}
返回处理程序;
}
公共静态字符串use_util(){
LOGGER.log(Level.INFO,“使用了UTIL!”);
return“只是我不知道……一根绳子,伙计。”;
}
公共静态void main(字符串[]args){
System.out.println(Util.use_Util());
}
}
但是,在第一次调用
use_util
时,会出现nullpointerexception,说明
LOGGER
为null:

$javac Util.java
$java -Xmx128M -Xms16M Util
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
    at java.util.logging.Logger.addHandler(Logger.java:1748)
    at Util.createFileHandler(Util.java:14)
    at Util.<clinit>(Util.java:8)
$javac Util.java
$java-Xmx128M-Xms16M Util
线程“main”java.lang.ExceptionInInitializeError中出现异常
原因:java.lang.NullPointerException
位于java.util.logging.Logger.addHandler(Logger.java:1748)
位于Util.createFileHandler(Util.java:14)
at Util.(Util.java:8)
根据Java规范:

然后,初始化值为编译时>常量表达式的接口的最终类变量和字段(§8.3.2.1、§9.3.1、§13.4.9、§15.28)。

接下来,按照文本顺序执行类的类变量初始值设定项和静态初始值设定项,或者执行接口的字段>初始值设定项,就像它们是单个块一样

因此,基于此,
LOGGER
应该在创建
fileHandler
之前进行初始化。尽管如此,
记录器
在初始化
文件处理程序
时似乎为空

为什么呢? 如何强制执行初始化命令

Caused by: java.lang.NullPointerException

at java.util.logging.Logger.addHandler(Logger.java:1748)
从我阅读本文的方式来看,类字段在这里不是问题。
LOGGER
不为null,执行对
LOGGER.addHandler()
的调用,但在内部失败

这是因为您将
filehandler
传递到调用中,而不是刚才在前一行中初始化的处理程序
handler
。 由于此时仍在
filehandler
的初始化执行中,因此它仍然是
null

从我阅读本文的方式来看,类字段在这里不是问题。
LOGGER
不为null,执行对
LOGGER.addHandler()
的调用,但在内部失败

这是因为您将
filehandler
传递到调用中,而不是刚才在前一行中初始化的处理程序
handler

由于此时您仍在
filehandler
的初始化执行中,因此它仍然是
null

您应该始终提供完整的堆栈跟踪。如果为了简洁而编辑它们,很难理解发生了什么。。。或者出于任何原因。我将代码扩展为可运行的。。谢谢您指出,我将扩展跟踪。您应该始终提供完整的跟踪。如果为了简洁而编辑它们,很难理解发生了什么。。。或者出于任何原因。我将代码扩展为可运行的。。谢谢你指出这一点,我将延伸痕迹。