强制在 start() 方法之前执行静态块

Force static block to be executed before start() method

我正在为我的项目使用 JavaFX,我有两个 classes - MainApp class 和 Database class.

非常简化的实现如下所示:

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

只有数据库class实现的相关部分如下(请注意,我已经声明并实现了提到的方法中出现的变量,我只是不将它们粘贴在这里以保持代码简短)

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 class 中的静态块在覆盖 start()[=27= 后执行] 方法。因此,当我访问数据库 class 的属性时,它们尚未初始化。

有没有办法在启动方法之前强制调用静态块?我选择了错误的方法吗?我应该在 start() 方法之外的其他地方开始使用数据库吗?

I am getting null pointer exception because of this: static block in Database class is executed after overridden start() method. Therefore, when I access properties of Database class, they are not initialized yet.

不,这不是问题所在。静态初始化程序在加载 class 时执行,这应该发生在之前(它总是在使用 class 中的 static 常量以外的任何内容之前完成。)

Database.setUserName(username);

或更早。

问题可能是 userNamepassword 尚未分配(尽管没有更多代码很难判断)。

我不建议使用 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 class。

顺便说一句:如果您需要在 Applicationstart 方法运行之前初始化某些东西,应该在应用程序 class 的覆盖 init() method 中完成.