Java &引用;从内部类引用的局部变量必须是final或实际上是final如何修复?

Java &引用;从内部类引用的局部变量必须是final或实际上是final如何修复?,java,Java,我见过其他线程也有类似的问题,但是在这些线程中,解决方案是创建一个带有值副本的最终变量,以便该变量实际上是最终变量。然而,我的问题源于这样一个事实:产生错误的变量是一个包含类实例的2D数组 以下是发生错误的控制器类的代码: package Controller; import Model.Die; import View.GameWindow; import View.HelpWindow; import java.awt.event.ActionEvent; import java.awt.

我见过其他线程也有类似的问题,但是在这些线程中,解决方案是创建一个带有值副本的最终变量,以便该变量实际上是最终变量。然而,我的问题源于这样一个事实:产生错误的变量是一个包含类实例的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
                }
            });
        }
    }
}
}
包装控制器;
进口模具;
导入View.GameWindow;
导入View.HelpWindow;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.BufferedReader;
导入java.io.FileReader;
导入java.io.IOException;
公共类控制器{
私人游戏窗口视图;
私有静态整数pos[]=新整数[2];
专用模具布局[];
私有字符串createdWord;
公共控制员(){
视图=新游戏窗口();
addHelpListener();
addSubmitListener();
diceLayout=view.getDice();
}
私有void submitWord(字符串字){
布尔有效=校验有效字(字);
如果(有效){
System.out.println(“单词'”+word+“'是有效的。”);
}else{System.out.println(“单词'+word+''无效。”);}
}
专用布尔校验字(字符串字){
布尔值validSpell=validWordDic(字);
布尔连接=检查字连接(字);
如果(validSpell&已连接){
返回true;
}否则{
返回false;
}
}
私有静态布尔值validWordDic(字符串字){
word=word.toLowerCase();
试一试{
BufferedReader in=new BufferedReader(新文件阅读器(“C:\\Users\\sambe\\Desktop\\IPT\\BoggleGame\\res\\dictionary.txt”);
字符串str;
而((str=in.readLine())!=null){
if(str.indexOf(word)!=-1){
返回true;
}
}
in.close();
}捕获(IOE异常){
e、 printStackTrace();
}
返回false;
}
公共布尔校验字连接(字符串字){
word=word.toLowerCase();
字符串字母[]=单词。拆分(“”);
对于(int i=0;i这里:

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

这应该做到:

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

for(int i=0;i与数组无关,而是与循环计数器有关。由于
i
j
不是有效的最终值(它们由循环递增),因此不能在匿名类中使用

diceLayout[i][j].setClicked(true);
           ^
       error here (and if you fixed that, it would appear at j)
您可以将
Die
提取到局部变量中,因此只能在侦听器外部访问
i
j

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); 
                }
            });
        }
    }
}
private void addDiceListeners()
{
对于(int i=0;i<4;i++)
{
对于(int j=0;j<4;j++)
{
模具=模具布局[i][j];
addActionListener(新ActionListener()
{
@凌驾
已执行的公共无效操作(操作事件e)
{
die.setClicked(true);
}
});
}
}
}
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); 
                }
            });
        }
    }
}