[英]"Local variables referenced from an inner class must be final or effectively final" - How to fix?
I've seen other threads with a similar issue, however in those threads the solution was to create a final variable with a copy of the values so that the variable is effectively final.我见过有类似问题的其他线程,但是在这些线程中,解决方案是创建一个带有值副本的最终变量,以便该变量实际上是最终的。 However, my issue derives from the fact that the variable that produces the error is a 2D array holding instances of a class.
但是,我的问题源于这样一个事实,即产生错误的变量是一个包含类实例的二维数组。
Here is code for the Controller class in which the error is happening:这是发生错误的 Controller 类的代码:
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
}
});
}
}
}
}
If anyone has any suggestions as to how I can fix this, it would be greatly appreciated.如果有人对我如何解决此问题有任何建议,将不胜感激。 Thanks!
谢谢!
It is not about the array, it's about the loop counters.这不是关于数组,而是关于循环计数器。 Since
i
and j
are not effectively final (they are incremented by the loops), they cannot be used in the anonymous class.由于
i
和j
不是最终的(它们由循环递增),因此它们不能在匿名类中使用。
diceLayout[i][j].setClicked(true);
^
error here (and if you fixed that, it would appear at j)
You can extract the Die
into a local variable and hence only access i
and j
outside the listener:您可以将
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);
}
});
}
}
}
Here:这里:
diceLayout[i][j].setClicked(true); //Error Occurs here
Your problem are i and j.你的问题是 i 和 j。 These are local variables from the enclosing method.
这些是来自封闭方法的局部变量。 And of course: those are loop counters, therefore you can't make them final.
当然:那些是循环计数器,因此您不能将它们设为最终。
This should do:这应该做:
for(int i = 0; i<4; i++) {
for(int j = 0; j<4; j++) {
final int finalRow = i;
final int finalColumn = j;
to then use the two final copies you just created instead of i and j.然后使用您刚刚创建的两个最终副本而不是 i 和 j。 Or, you go as the other answer suggests and fetch the actual
Die
object to use (as final).或者,您按照另一个答案的建议进行操作并获取要使用的实际
Die
对象(作为最终对象)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.