java - 在 Java 中将静态字段设置为 Final

标签 java jdbc static jndi final

看下面的代码片段,给出的场景是从 Tomcat 服务器的数据库连接池中获取数据库连接。

public final class DatabaseConnection {

    private static DataSource dataSource;

    static {
        try {
            Context initContext = new InitialContext();
            Context context = (Context) initContext.lookup("java:comp/env");
            dataSource = (DataSource) context.lookup("jdbc/assignment_db");
        } catch (NamingException e) {
            Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

我想在类final中创建唯一的字段。如果我将其设为 final 字段,编译器会提示,

variable dataSource might not have been initialized.

在成为final后,如果在声明处初始化为null,则在try block 中进一步初始化该字段被严格禁止导致编译错误,

cannot assign a value to final variable dataSource.

NamingException 是一个受检查的异常。因此,必须将其捕获或声明将其抛出。

<小时/>

早些时候,有一个不同的场景。该策略是使用 Apache DBCP,如下所示。

public final class DatabaseConnection {

    private static final BasicDataSource basicDataSource;

    static {
        basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        basicDataSource.setUrl("jdbc:mysql://localhost:3306/assignment_db");
        basicDataSource.setUsername("Tiny");
        basicDataSource.setPassword("root");
    }

    public static Connection getConnection() throws SQLException {
        return basicDataSource.getConnection();
    }
}

其中,该字段可以声明为final,因为没有检查异常,并且不需要try...catch

我可以以某种方式使 dataSource 像第一种情况一样最终吗?

最佳答案

这让我陷入困境很多次,直到我找到了解决方法。您可以在 static block 中使用临时变量,并在 try-catch 使用该变量结束后分配 dataSource:

private static final DataSource dataSource;

static
{
    DataSource tempDataSource = null;
    try
    {                
        Context initContext = new InitialContext();
        Context context = (Context) initContext.lookup("java:comp/env");
        tempDataSource = (DataSource) context.lookup("jdbc/assignment_db");
    } catch (NamingException ex) {
        Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
    }
    dataSource = tempDataSource;
}

但是,我宁愿不正常遵循,仅当 dataSource 未初始化时才从 catch block 抛出异常,在这种情况下,您不需要局部变量:

static
{
    try
    {                
        Context initContext = new InitialContext();
        Context context = (Context) initContext.lookup("java:comp/env");
        dataSource = (DataSource) context.lookup("jdbc/assignment_db");
    } catch (NamingException ex) {
        Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
        throw new ExceptionInInitializerError("dataSource not initialized");
    }
}

关于java - 在 Java 中将静态字段设置为 Final,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21644195/

相关文章:

java - 我应该如何使用jdbc将vararray从plsql发送到java?

c - 比较指针与静态变量的行为是什么?

java - 与 JOptionPane 相关的字符串连接

java - 使用 ANTLR 4.7 : need to parse fragments in string literals 解析 Swift

java - 不能从静态上下文中引用非静态变量

C++,静态与命名空间与单例

java - java中的静态变量和多线程

java - 为什么 Java 类加载器找不到我的接口(interface)?

java - 从 java 调用存储过程时出错

jpa - 找不到适用于 jdbc :mysql://localhost:3306/rom (Payara 5, Windows 10 的合适驱动程序