我写了以下代码:
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();
}
}
但即使这个对我来说听起来也不正确:只有在第一次使用时才会抛出异常(我知道它会在启动时因为我必须进行检查),加载类时是。所以从理论上讲,第一种方式更为正确。 :\
我该怎么办?哪种方式更正确?
问题是具有静态初始化程序 NEEDS 的类都包含驱动程序和配置,因此在它们都可用之前不应该。 :\
答案 0 :(得分:3)
为什么不在main()
方法中检查这些条件,或者main()
方法调用的内容?应用程序的入口点只能输入一次。一个简单的方法比静态初始化器和类加载器技巧要好得多。
public static void main(String[] args) {
if (!requirementsMet()) {
System.exit(1);
}
//proceed with app...
}
private static boolean requirementsMet() {
// check if DB driver can be loaded, and other non-recoverable errors
}
答案 1 :(得分:0)
您可以使用Singleton类。 e.g。
DBConfigProvider {
private Configuration conf = null
private DBConfigProvider() {
/* 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
}
private static DBConfigProvider instance = null;
public static Configuration getConf() {
if (instance == null) {
instance = new DBConfigurationProvider();
}
return instance.conf;
}
}