简体   繁体   中英

Getting error “Cannot refer to a non-final variable inside an inner class defined in a different method”

I'm new to both Java and Android programming. I get the error with this code:

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView tView=(TextView) findViewById(R.id.txt);
    Button btn=(Button) findViewById(R.id.button);
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            tView.setText("Blah Blah");     
        }
    });

But when I declare reference type "tView" out of the onCreate() method simply the error goes away then the code would be like this:

public class MainActivity extends ActionBarActivity {

TextView tView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tView=(TextView) findViewById(R.id.txt);
    Button btn=(Button) findViewById(R.id.button);
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            tView.setText("Blah Blah");     
        }
    });

So what's the difference when I declare reference type "tview" inside the method onCreate() and outside it?

This has to do with the scope of the variable. When you define the variable inside the method, the variables scope is only within that method. When you create your onClickListener , you are creating an anonymous inner class. This means that you would have to do this, to make the code work:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView tView=(TextView) findViewById(R.id.txt);
        Button btn=(Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                tView.setText("Blah Blah");     
            }
        });

This prevents the tView variable from changing.

When you code the other way, the scope changes, and the variable is seen by the entire class, rather than just the method.

好吧,我经过一番搜索后发现,当我们在内部类中使用非最终局部变量时,当内部类尝试更改方法结束后不存在的局部变量时,它可能会引起一些意想不到的奇怪问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM