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

时间:2014-11-27 07:12:33

标签: java multithreading swing inner-classes final

请查看以下代码

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

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

Object[]row = {totalAmount};
model.addRow(row);

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

1 个答案:

答案 0 :(得分:4)

您可以创建 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