我写了以下代码:
static {
/* Attempts to load JDBC driver */
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new DBConfigurationException("JDBC Driver not found.", e);
}
/* Attempts to load configuration */
conf = loadConfiguration(); //this may throw some subclasses of RuntimeException
}
因为我希望 JDBC 驱动程序和配置只加载一次。
我想在启动时做这样的事情(我会尽可能简化):
public static void main(String[] args) {
try {
// load the class that contains the code above
} catch (DBConfigurationException e) {
// display proper error message using JOptionPane, then quit
} catch (MissingConfigurationException e) {
// display proper error message using JOptionPane
// show a JDialog and allow user to input and store a configuration
} catch (InvalidConfigurationException e) {
// display proper error message using JOptionPane
// show a JDialog and allow user to input and store a configuration
}
/* if everything it's ok */
// do some other checks in order to decide which JFrame display first.
}
现在,问题是如果发生异常,JVM 将抛出广告ExceptionInInitializerError
并且不会构造对象。可能我仍然理解出了什么问题,抓住ExceptionInInitializerError
(即使这对我来说听起来不对)并检查它的原因(我仍然没有尝试这样做,但我认为这是可能的)。
我需要那个对象,因为如果异常是可恢复的(例如 MissingConfigurationException),程序将不会退出并且需要那个对象。
我应该避免使用静态初始化程序吗?我可以做类似的事情:
private static final Configuration conf = null;
Constructor() {
if (conf == null) {
/* Attempts to load JDBC driver */
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new DBConfigurationException("JDBC Driver not found.", e);
}
/* Attempts to load configuration */
conf = loadConfiguration();
}
}
但即使这对我来说听起来也不正确:异常可能仅在第一次尝试使用时抛出(我知道这将在启动时进行,因为我必须进行检查),即加载类时。所以理论上第一种方法会更正确。:\
我应该怎么办?哪种方式更正确?
问题是具有静态初始化程序的类既需要驱动程序又需要配置,因此在它们都可用之前不应该使用它。:\