java - 强制静态 block 在 start() 方法之前执行

标签 java javafx static-block

我在我的项目中使用 JavaFX,并且有两个类 - MainApp 类和 Database 类。

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

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

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

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 类中的静态 block 在重写 start() 方法之后执行。因此,当我访问数据库类的属性时,它们尚未初始化。

有没有办法在启动方法之前强制调用静态 block ?我选择了错误的方法吗?我应该在 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.

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

Database.setUserName(username);

或更早。

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

我不建议使用静态数据来传递信息,而是以允许访问非静态对象以便在需要时与数据库进行通信的方式设计应用程序。

但是,您可以通过将代码从静态初始值设定项移动到 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类。

顺便说一句:如果您需要在 Applicationstart 方法运行之前初始化某些内容,则应该在重写的 init() method 中完成。应用程序类的。

关于java - 强制静态 block 在 start() 方法之前执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40961493/

相关文章:

java - javafx编程中的时钟动画

java - 静态 block 和静态字段有什么区别?

java - 比较字符串数组的数组列表

java - 什么是 uber JAR 文件?

java - 如何删除字符串中 $ 后面的空格?

java - java中最好的XML解析库是哪个

java - 如何控制JavaFX TextArea自动滚动?

java - togglegroup.getSelectedToogle() 始终返回 null JavaFX

java - 为什么静态 block 不能访问其后定义的静态变量

java - 枚举 - 静态和实例 block