【发布时间】:2014-05-19 21:50:17
【问题描述】:
在寻找我的静态初始化块不执行的原因时,我发现类中的静态初始化器永远不会执行 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);
}
}
}
但是那个静态块仍然不会执行!
保证静态块执行的正确方法是什么?
更新:下面的所有答案都提到了引用类以便运行静态初始化的要求。所以我再次查看了我的堆栈跟踪并验证了该类确实被引用(否则,为什么它会在同一个类方法中抛出异常?)
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));
而且那个静态块仍然不会执行。
所以我尝试显式实例化它:
HibernateUtil justExecTheDarnStaticBlock = new HibernateUtil();
mProps.load(ServiceUtils.class.getResourceAsStream(HibernateUtil.MYWS_PROPS));
但是那个静态块仍然不会执行!
我在这里错过了什么?
【问题讨论】:
-
I found that a static initializer in a class never executes if it references a final.这不是真的。您预计static块何时执行? -
当 JVM(具体来说是类加载器)加载 StaticClass(在代码中第一次引用它时)时,正在运行静态初始化块。我对没有final的要求的理解来自这里:stackoverflow.com/a/16853836/1864054我错过了什么?
-
这与
static final字段有关,这些字段也是常量变量,与初始化块无关。
标签: java