我已经在工厂类的构造函数中为工厂类的某些配置设置了一个私有静态属性对象。
public class BussinessServiceFactory {
private static final BussinessServiceFactory factory = new BussinessServiceFactory();
public static BussinessServiceFactory createBussinessServiceFactory(){
return factory;
}
private BussinessServiceFactory(){
InputStream in = BussinessServiceFactory.class.getClassLoader().getResourceAsStream("factory/bussinessservice.properties");
try {
bsConfig.load(in);
} catch (IOException exception) {
// TODO Auto-generated catch block
throw new RuntimeException(exception);
}
}
private static Properties bsConfig = new Properties();
public <T> T createBussinessService(Class<T> clazz){
try {
String clazzName = clazz.getSimpleName();
String name = bsConfig.getProperty(clazzName);
return (T) Class.forName(name).newInstance();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException exception) {
throw new RuntimeException(exception);
}
}
}
但是,当我初始化类时,它会抛出NullPointerException
。
java.lang.NullPointerException
at factory.BussinessServiceFactory.<init>(BussinessServiceFactory.java:15)
at factory.BussinessServiceFactory.<clinit>(BussinessServiceFactory.java:8)
... 24 more
然后,如果我将属性对象更改为非静态对象,则问题就解决了。但我仍然感到困惑的原因是为什么会发生这种情况以及如何以这种方式解决它。
答案 0 :(得分:1)
静态初始化器自上而下完成。因此,在加载类factory
时会初始化静态字段BussinessServiceFactory
。此静态初始值设定项调用BussinessServiceFactory
的构造函数,因此最终加载对静态字段bsConfig
的引用。此时此字段尚未初始化,因为我们仍然在factory
字段的静态初始化程序块中。因此,NullPointerException。
修正此问题1)将bsConfig
字段重新排序到factory
字段之上,或者更好的是,通过使bsConfig
字段成为实例字段(这是你修复它所做的,我相信是解决这个问题的最佳方法)。
有关静态初始化顺序的详细信息,请参阅http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4。
附录:
stacktrace揭示了你的问题的根源。 stacktrace中的clinit
代表 cl ass init ,因此,您可以判断问题是加载了一个类。