"Local variables referenced from an inner class must be final or effectively final" - 如何解决?



我见过其他线程有类似的问题,但是在这些线程中,解决方案是创建一个带有值副本的最终变量,以便该变量实际上是最终的。但是,我的问题源于这样一个事实,即产生错误的变量是保存类实例的 2D 数组。

下面是发生错误的控制器类的代码:

package Controller;
import Model.Die;
import View.GameWindow;
import View.HelpWindow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Controller {
private GameWindow view;
private static int pos[] = new int[2];
private Die diceLayout[][];
private String createdWord;
public Controller(){
view = new GameWindow();
addHelpListener();
addSubmitListener();
diceLayout = view.getDice();
}
private void submitWord(String word){
boolean valid = checkValidWord(word);
if(valid){
System.out.println("The word ‘"+word+"‘ is valid.");
}else{System.out.println("The word ‘"+word+"‘ is not valid.");}
}
private boolean checkValidWord(String word){
boolean validSpell = validWordDic(word);
boolean connected = checkWordConnected(word);
if(validSpell&&connected){
return true;
}else{
return false;
}
}
private static boolean validWordDic(String word){
word=word.toLowerCase();
try {
BufferedReader in = new BufferedReader(new FileReader("C:\Users\sambe\Desktop\IPT\BoggleGame\res\dictionary.txt"));
String str;
while ((str = in.readLine()) != null) {
if (str.indexOf(word) != -1) {
return true;
}
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public boolean checkWordConnected(String word){
word = word.toLowerCase();
String letters[] = word.split("");
for(int i = 0; i<4; i++){
for(int j = 0; j<4; j++){
if(letters[0]==diceLayout[i][j].getText()){
pos[0]=i;
pos[1]=j;
}
}
}
return true;
}
private void addHelpListener(){
view.getHelpButton().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) { 
HelpWindow helpWin = new HelpWindow();
System.out.println("done");
} 
});
}
private void addSubmitListener(){
view.getSubmitButton().addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("done");
if(view.getSubmitField().getText()!=null){
submitWord(view.getSubmitField().getText());
}else{
submitWord(createdWord);
createdWord="";
}
view.getSubmitField().setText("");
} 
});
}
private void addDiceListeners(){
for(int i = 0; i<4; i++){
for(int j = 0; j<4; j++){
diceLayout[i][j].addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
diceLayout[i][j].setClicked(true); //Error Occurs here
}
});
}
}
}
}

如果有人对我如何解决此问题有任何建议,将不胜感激。谢谢!

这不是关于数组,而是关于循环计数器。由于ij实际上不是最终的(它们由循环递增(,因此它们不能在匿名类中使用。

diceLayout[i][j].setClicked(true);
^
error here (and if you fixed that, it would appear at j)

您可以将Die提取到局部变量中,因此只能在侦听器外部访问ij

private void addDiceListeners()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
Die die = diceLayout[i][j];
die.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
die.setClicked(true); 
}
});
}
}
}

在这里:

diceLayout[i][j].setClicked(true); //Error Occurs here

你的问题是 i 和 j。这些是封闭方法中的局部变量。 当然:这些是循环计数器,因此您无法使它们成为最终计数器。

这应该可以做到:

for(int i = 0; i<4; i++) {
for(int j = 0; j<4; j++) {
final int finalRow = i;
final int finalColumn = j;

然后使用您刚刚创建的两个最终副本,而不是 i 和 j。或者,您按照另一个答案的建议进行操作,并获取要使用的实际Die对象(作为最终对象(。

相关内容

最新更新