2

我写了以下代码:

    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();
    }
}

但即使这对我来说听起来也不正确:异常可能仅在第一次尝试使用时抛出(我知道这将在启动时进行,因为我必须进行检查),加载类时。所以理论上第一种方法会更正确。:\

我应该怎么办?哪种方式更正确?

问题是具有静态初始化程序的类既需要驱动程序又需要配置,因此在它们都可用之前不应该使用它。:\

4

2 回答 2

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
}
于 2012-09-06T18:04:36.103 回答
0

您可以使用单例类。例如

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;
    }
}
于 2012-09-06T18:24:43.827 回答