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ドライバーと構成を1回だけロードしたいからです。

私はスタートアップでこのようなことをしたかった(私は可能な限り単純化する):

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()か? アプリケーションのエントリポイントは 1 回しか入力できません。シンプルなアプローチは、静的イニシャライザーやクラスローダーのトリッキーよりもはるかに優れています。

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 に答える