2016-12-04 5 views
0

Я использую JavaFX для своего проекта, и у меня есть два класса - MainApp класс и База данных класс.Форсировать статический блок перед запуском()

Очень упрощенная реализация будет выглядеть следующим образом:

public class MainApp extends Application { 
    @Override 
    public void start(Stage stage) throws Exception { 

    // Getting username & password doing some initialization, etc. 

    Database.setUserName(username); 
    Database.setPassword(password); 
    Database.testConnection(); 
    } 

    // This method was pretty much generated by IDE 
    public static void main(String[] args) 
    { 
     launch(args); 
    } 
} 

только соответствующая часть реализации класса Database выглядит следующим образом (обратите внимание, что я объявил и реализованы переменные, которые появляются в указанных методах, я просто не вставить они здесь, чтобы сохранить код короткий)

public class Database { 

private static OracleDataSource dataSource; 

static { 
     try { 
      dataSource = new OracleDataSource(); 
      dataSource.setURL("myjdbcaddress"); 
      dataSource.setUser(userName); 
      dataSource.setPassword(password); 

      System.out.print("Static block executed..."); 
     } 
     catch (SQLException e) 
     { 
      System.out.print("Static block caught..."); 
      throw new ExceptionInInitializerError("Initial Database Connection not established. Sorry."); 
     } 
    } 


    public static Connection getConnection() 
    { 
     Connection conn = null; 

     try 
     { 
      conn = dataSource.getConnection(); 
      if (conn != null) 
       isConnected = true; 
     } 
     catch (SQLException e) 
     { 
      e.printStackTrace(); 
     } 

     return conn; 
    } 

} 

Я получаю исключение нулевого указателя из-за этого: статический блок в базе данных класса выполняются после того, как переопределяется старт() способ. Поэтому, когда я обращаюсь к свойствам класса Database, они еще не инициализированы.

Есть ли способ заставить статический блок вызова перед запуском? Я выбрал неправильный подход? Должен ли я начать работу с базой данных где-то еще, чем start() метод?

ответ

1

Я получаю исключение из null указателя из-за этого: статический блок в классе базы данных выполняется после переопределенного метода start(). Поэтому, когда я обращаюсь к свойствам класса Database, они еще не инициализированы.

Нет, это не проблема. Статический инициализатор выполняется при загрузке класса, которое должно произойти перед (Это всегда делается, прежде чем что-либо иное, чем static константы в классе используется.)

Database.setUserName(username); 

или ранее.

Проблема, вероятно, состоит в том, что userName и password еще не присвоены (хотя это трудно сказать без дополнительного кода).

Я не рекомендую использовать данные static для передачи информации, но вместо этого создавайте приложение таким образом, чтобы обеспечить доступ к нестационарному объекту для связи с базой данных там, где это необходимо.

Однако вы могли бы решить вашу проблему, переместив код из статического инициализатора к static методу:

public class Database { 

    private static OracleDataSource dataSource; 

    public static void login(String userName, String password) { 
     try { 
      dataSource = new OracleDataSource(); 
      dataSource.setURL("myjdbcaddress"); 
      dataSource.setUser(userName); 
      dataSource.setPassword(password); 

      System.out.print("Static block executed..."); 
     } catch (SQLException e) { 
      throw new IllegalStateException("Initial Database Connection not established. Sorry.", e); 
     } 
    } 

    ... 
} 
Database.login(username, password); 
Database.testConnection(); 

Но опять же: Старайтесь избегать использования таких Database класса, который позволяет получить доступ из везде.

BTW: Если вам нужно инициализировать что-либо перед использованием метода start для прогона Application, это должно быть сделано в переопределении init() method класса приложения.

Смежные вопросы