Java 无法在其他方法中定义的内部类中引用非最终变量i

Java 无法在其他方法中定义的内部类中引用非最终变量i,java,android,Java,Android,我有“无法引用在不同方法中定义的内部类中的非最终变量i”错误。。。我哪里出错了?。。。我刚开始学习android和java编程 public class Tictac extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState

我有“无法引用在不同方法中定义的内部类中的非最终变量i”错误。。。我哪里出错了?。。。我刚开始学习android和java编程

public class Tictac extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

        Button button[] = new Button[9];
        button[0]= (Button) findViewById(R.id.button1);
        button[1] = (Button) findViewById(R.id.button2);
        button[2] = (Button) findViewById(R.id.button3);
        button[3] = (Button) findViewById(R.id.button4);
        button[4] = (Button) findViewById(R.id.button5);
        button[5] = (Button) findViewById(R.id.button6);
        button[6] = (Button) findViewById(R.id.button7);
        button[7] = (Button) findViewById(R.id.button8);
        button[8] = (Button) findViewById(R.id.button9);


        final TextView text = (TextView) findViewById(R.id.textView1);

        final ImageView img[] = new ImageView[9];
        img[0] = (ImageView) findViewById(R.id.img1);
        img[1] = (ImageView) findViewById(R.id.img2);
        img[2] = (ImageView) findViewById(R.id.img3);
        img[3] = (ImageView) findViewById(R.id.img4);
        img[4] = (ImageView) findViewById(R.id.img5);
        img[5] = (ImageView) findViewById(R.id.img6);
        img[6] = (ImageView) findViewById(R.id.img7);
        img[7] = (ImageView) findViewById(R.id.img8);
        img[8] = (ImageView) findViewById(R.id.img9);
        final ImageView imSq[] = new ImageView[9];
        imSq[0] = (ImageView) findViewById(R.id.imSq1);
        imSq[1] = (ImageView) findViewById(R.id.imSq2);
        imSq[2] = (ImageView) findViewById(R.id.imSq3);
        imSq[3] = (ImageView) findViewById(R.id.imSq4);
        imSq[4] = (ImageView) findViewById(R.id.imSq5);
        imSq[5] = (ImageView) findViewById(R.id.imSq6);
        imSq[6] = (ImageView) findViewById(R.id.imSq7);
        imSq[7] = (ImageView) findViewById(R.id.imSq8);
        imSq[8] = (ImageView) findViewById(R.id.imSq9);


        for(int i =0;i <=8;i++){
        if(i%2==0){
             button[i].setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
        **HERE-->**       img[i].setVisibility(2);
                         text.setText("COOL");

                    }
                    });
        }
        else{   
             button[i].setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
         **HERE-->**        imSq[i].setVisibility(2);
                         text.setText("COOL");

                    }
                    });
    }



        }

}      
公共类Tictac扩展活动{
/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
按钮按钮[]=新按钮[9];
按钮[0]=(按钮)findViewById(R.id.button1);
按钮[1]=(按钮)findViewById(R.id.button2);
按钮[2]=(按钮)findViewById(R.id.button3);
按钮[3]=(按钮)findViewById(R.id.button4);
按钮[4]=(按钮)findViewById(R.id.button5);
按钮[5]=(按钮)findViewById(R.id.button6);
按钮[6]=(按钮)findViewById(R.id.button7);
按钮[7]=(按钮)findViewById(R.id.button8);
按钮[8]=(按钮)findViewById(R.id.button9);
最终文本视图文本=(文本视图)findViewById(R.id.textView1);
最终图像视图img[]=新图像视图[9];
img[0]=(ImageView)findViewById(R.id.img1);
img[1]=(ImageView)findViewById(R.id.img2);
img[2]=(ImageView)findViewById(R.id.img3);
img[3]=(ImageView)findviewbyd(R.id.img4);
img[4]=(ImageView)findViewById(R.id.img5);
img[5]=(ImageView)findViewById(R.id.img6);
img[6]=(ImageView)findViewById(R.id.img7);
img[7]=(ImageView)findViewById(R.id.img8);
img[8]=(ImageView)findViewById(R.id.img9);
最终图像视图imSq[]=新图像视图[9];
imSq[0]=(ImageView)findViewById(R.id.imSq1);
imSq[1]=(ImageView)findViewById(R.id.imSq2);
imSq[2]=(ImageView)findViewById(R.id.imSq3);
imSq[3]=(ImageView)findViewById(R.id.imSq4);
imSq[4]=(ImageView)findViewById(R.id.imSq5);
imSq[5]=(ImageView)findViewById(R.id.imSq6);
imSq[6]=(ImageView)findViewById(R.id.imSq7);
imSq[7]=(ImageView)findViewById(R.id.imSq8);
imSq[8]=(ImageView)findViewById(R.id.imSq9);
对于(int i=0;i**img[i]),设置可见性(2);
text.setText(“酷”);
}
});
}
否则{
按钮[i]。setOnClickListener(新视图。OnClickListener(){
公共void onClick(视图v){
**这里-->**imSq[i].setVisibility(2);
text.setText(“酷”);
}
});
}
}
}      

}

错误消息准确地说明了问题所在:
i
变量不是final,但您试图在匿名内部类中引用它

您可以这样做:

for (int i = 0; i <= 8;i++) {
  if (i % 2 == 0) {
     final int j = i;
     button[i].setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
           img[j].setVisibility(2);
           text.setText("COOL");
         }
     });
  }
}
发件人:

在内部类中使用但未声明的任何局部变量、形式方法参数或异常处理程序参数都必须声明为final。在内部类中使用但未声明的任何局部变量必须在内部类主体之前明确赋值(§16)


您可以创建一个方法,如下所示:

private void method(final Button btn, final ImageView img) {
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            img.setVisibility(2);
            text.setText("COOL");
        }
    });
}
在for i循环中使用它。
这应该有效(未测试)

问题是:虽然数组是最终的,但这些数组的元素不是最终的。@Cephron:不,这根本不是问题。当有人单击您的按钮时,“i”将是什么值?好的。。谢谢你:)。。这不是我想做的。。但是你的建议奏效了。。那么,再次感谢您为什么在内部类中使用但未声明的任何局部变量、正式方法参数或异常处理程序参数都必须声明为final?@Roberto:这是因为该值有效地传递给了匿名内部类的编译器生成的构造函数。通过将变量设置为最终变量,可以避免在内部类中读取“已更改”的变量,并期望看到新值,而实际上只看到旧值。
private void method(final Button btn, final ImageView img) {
    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            img.setVisibility(2);
            text.setText("COOL");
        }
    });
}