Java - 从内部类引用变量必须是final / effective final loop

时间:2015-11-13 22:43:48

标签: java final

我正在尝试为Chess / Checkers游戏开发GUI。当尝试将ActionListeners添加到按钮时,Netbeans似乎给了我一大堆错误,其中的建议似乎无法解决问题。

以下是相关代码的一部分:

for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                squares[i][j].addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        if (!pressed) {
                            pressed = true;
                            fromR = i;
                        }
                        throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
    }
square [] [] []是存储所有按钮的数组;错误发生在fromR = i;

有没有更好的方法将ActionListeners添加到存储在数组中的按钮中?

1 个答案:

答案 0 :(得分:2)

问题是你在动作监听器中指的是 i 并且它在不断变化。

一种选择是将 i 复制到新的 int ,例如 iValue

for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
        final int iValue = i;
        squares[i][j].addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (!pressed) {
                    pressed = true;
                    fromR = iValue;
                }
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }
}

虽然这很笨拙。

更清洁的替代方法是提取方法:

for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
        addActionListenerTo(squares[i][j], i);
    }
}

这是方法:

private void addActionListenerTo(WhateverThisIs square, int i) {
    square.addActionListener(e -> {
        if (!pressed) {
            pressed = true;
            fromR = i;
        }
        throw new UnsupportedOperationException("Not supported yet.");
    });
}

另一种选择是让所有方块都知道他们的等级和档案:

final class Square {
    final int rank;
    final int file:
    Square(int rank, int file) {
        this.rank = rank;
        this.file = file;
    }
}

将它们放在集合中然后你可以这样做:

squares.stream().forEach(square -> {
    square.addActionListener(e -> {
        if (!pressed) {
            pressed = true;
            fromR = square.rank;
        }
        throw new UnsupportedOperationException("Not supported yet.");
    });
});