Java - 从内部 class 引用变量必须是最终的/有效的最终循环

Java - referencing variables from inner class must be final / effectively final loop

我正在尝试为国际象棋/西洋跳棋游戏开发 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.");
                }
            });
        }
    }

squares[][]是存放所有按钮的数组;错误发生在 fromR = i;

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

问题是您指的是动作侦听器内部的 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.");
    });
});