从内部类引用的局部变量必须是 final 或有效 final

Pea*_*Gen 0 java swing multithreading final inner-classes

请看下面的代码

private void displayInitialRevenue_Method() {
    //Get the dates from the combo
    String selectedCouple = revenueYearCombo.getSelectedItem().toString();
    if (selectedCouple.equals("Select Year")) {
        return;
    }
    String[] split = selectedCouple.split("/");
    //Related to DB
    double totalAmount = 0.0;
    //Get data from the database
    dbConnector = new DBHandler();
    dbConnector.makeConnection();
    DefaultTableModel model = (DefaultTableModel) initialRevenueTable.getModel();
    model.setRowCount(0);
    ResultSet selectAllDetails = dbConnector.selectAllDetails("SQL CODE ");
    try {
        if (selectAllDetails.isBeforeFirst() == false) {
            JOptionPane.showMessageDialog(null, "This table is empty");
        } else {
            while (selectAllDetails.next()) {
                String clientName = selectAllDetails.getString("Client Name");
                String providerName = selectAllDetails.getString("Provider Name");
                Double amountInvested = selectAllDetails.getDouble("Invest_Amount");
                //Update the table
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        Object[] row = {clientName, providerName, amountInvested};
                        model.addRow(row);
                    }
                });
                //Get the total
                totalAmount = totalAmount + amountInvested;
            }
            //Add the sum
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    Object[] blankRow = {null};
                    model.addRow(blankRow);
                    Object[] row = {totalAmount};
                    model.addRow(row);

                }
            });
        }
    } catch (SQLException sql) {
        JOptionPane.showMessageDialog(null, sql.getLocalizedMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

整个方法在另一个线程中运行。UI 更新正在内部运行SwingUtilities.InvokeLater()。但是请注意以下内容。

Object[]row = {totalAmount};
model.addRow(row);
Run Code Online (Sandbox Code Playgroud)

变量totalAmount不是最终的,也不能是最终的,因为它需要在上面计算while loop。因为它不是final我无法SwingUtilities.InvokeLater()在错误所说的内部使用它Local variables referred from inner class must be final or effectively final

Eri*_*rik 5

您可以创建一个附加变量,Final,然后将计算的最终结果复制到其中。

while (selectAllDetails.next()) {
            String clientName = selectAllDetails.getString("Client Name");
            String providerName = selectAllDetails.getString("Provider Name");
            Double amountInvested = selectAllDetails.getDouble("Invest_Amount");
            //Update the table
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    Object[] row = {clientName, providerName, amountInvested};
                    model.addRow(row);
                }
            });
            //Get the total
            totalAmount = totalAmount + amountInvested;
        }
final Double totalAmountInvested = totalAmount; // and now use this one in the Inner
Run Code Online (Sandbox Code Playgroud)