gpt4 book ai didi

java - 如何使静态初始化 block 执行?

转载 作者:行者123 更新时间:2023-12-02 03:19:28 25 4
gpt4 key购买 nike

在寻找为什么我的静态初始化 block 无法执行的解释时,我发现类中的静态初始化程序永远不会执行 if it references a final .

因此,我尝试通过从 MYWS_PROPS 中删除“final”来解决此问题:

public class HibernateUtil {
public static String MYWS_PROPS = "/myws.properties";

private static final Logger LOG = Logger.getLogger(HibernateUtil.class.getName());
private static final SessionFactory sessionFactory = buildSessionFactory();
private static Properties sProps;

static {
try {
sProps = new Properties();
sProps.load(ServiceUtils.class.getResourceAsStream(MYWS_PROPS));
LOG.info("Loaded (from " + MYWS_PROPS + ") connection url: " + sProps.getProperty("dburl"));
}
catch (IOException e) {
LOG.severe("Cannot find properties file " + MYWS_PROPS);
}
}



private static SessionFactory buildSessionFactory() {
try {
Configuration config = new Configuration();
config = config.configure("resources/hibernate.cfg.xml");
config.setProperty("hibernate.connection.url", sProps.getProperty("dburl")); // <== NullPointerException!
SessionFactory session = config.buildSessionFactory();
return session;
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

}

但是那个静态 block 仍然不会执行!

保证静态 block 执行的正确方法是什么?

<小时/>

更新:下面的所有答案都提到了引用该类的要求,以便静态初始化能够运行。因此,我再次查看堆栈跟踪并验证该类确实被引用(否则,为什么它会在同一个类方法中抛出异常?)

Caused by: java.lang.ExceptionInInitializerError
at com.corp.dept.proj.myws.HibernateUtil.buildSessionFactory(HibernateUtil.java:76)
at com.corp.dept.proj.myws.HibernateUtil.<clinit>(HibernateUtil.java:38)
at com.corp.dept.proj.myws.ServicePortImpl.<init>(ServicePortImpl.java:82)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
... 70 more
Caused by: java.lang.NullPointerException
at com.corp.dept.proj.myws.HibernateUtil.buildSessionFactory(HibernateUtil.java:67)
... 77 more

但为了安全起见,我尝试了 Class.forName 建议:

Class.forName("com.corp.dept.proj.myws.HibernateUtil");
mProps.load(ServiceUtils.class.getResourceAsStream(HibernateUtil.MYWS_PROPS));

那个静态 block 仍然不会执行。

所以我尝试显式实例化它:

HibernateUtil justExecTheDarnStaticBlock = new HibernateUtil();
mProps.load(ServiceUtils.class.getResourceAsStream(HibernateUtil.MYWS_PROPS));

但是那个静态 block 仍然不会执行!

我在这里缺少什么?

最佳答案

处理静态初始化时,顺序很重要

看下面的例子:

public class StaticTest {
private static final String someString = initSomeString();
private static final String someOtherString = initSomeOtherString();
private static final String whoops;

static {
System.out.println("static initializer");
whoops = "whoops";
}

public static void main(String[] args) {
System.out.println(someOtherString);
}

private static String initSomeString() {
System.out.println("initSomeString");
return "Initialised";
}

private static String initSomeOtherString() {
System.out.println("initSomeOtherString");
return whoops + "y daisy";
}
}

运行该类的结果如下:

initSomeString
initSomeOtherString
static initialiser
nully daisy

静态初始化按照声明的顺序发生,这意味着 initSomeOtherString() 在初始化的静态初始化 block 之前被调用哎呀哎呀。因此,此时 whoops 仍然是 null,因此生成的 Stringnully daisy 而不是 百日菊

如果我重新排列类,以便在静态初始化器之后初始化 someOtherString ,我会得到我想要的:

public class StaticTest {
private static final String someString = initSomeString();
private static final String whoops;

static {
System.out.println("static initialiser");
whoops = "whoops";
}

private static final String someOtherString = initSomeOtherString();

public static void main(String[] args) {
System.out.println(someOtherString);
}

private static String initSomeString() {
System.out.println("initSomeString");
return "Initialised";
}

private static String initSomeOtherString() {
System.out.println("initSomeOtherString");
return whoops + "y daisy";
}
}

打印

initSomeString
static initialiser
initSomeOtherString
whoopsy daisy

这是您遇到的行为并导致了您的问题。您通过调用 buildSessionFactory() 来初始化 sessionFactory,这依赖于初始化 sProps:

config.setProperty("hibernate.connection.url", sProps.getProperty("dburl")
^ This hasn't been initialised yet

解决方案? sessionFactory 的声明移至静态初始化程序 block 的下方

关于java - 如何使静态初始化 block 执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22916041/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com