Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it says that "Cannot refer to a non-final variable i inside an inner class defined in a different method"? [duplicate]

I have button click listener and in onCreate() method I have a local variable like

 onCreate() {

 super.onCreate();

 int i = 10;

 Button button = (Button)findViewById(R.id.button);

 button.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            i++;
        }   
    });

Why java asks for to make me final ?

like image 521
Khawar Raza Avatar asked Oct 21 '11 07:10

Khawar Raza


People also ask

Can we use Non final local variable inside a local inner class?

A local inner class cannot be instantiated from outside the block where it is created in. Till JDK 7, the Local inner class can access only the final local variable of the enclosing block. However, From JDK 8, it is possible to access the non-final local variable of enclosing block in the local inner class.

Can we use Non final local variables inside an anonymous class?

An anonymous class has access to the members of its enclosing class. An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

Can we declare variables inside method?

Local Variables We can put it in a method body. We declared num in the method body of main(). Variables declared inside a method are called local variables. Local variables can only be used within the method body.

How do you find the value of an inner class?

Accessing the Private Members Write an inner class in it, return the private members from a method within the inner class, say, getValue(), and finally from another class (from which you want to access the private members) call the getValue() method of the inner class.


2 Answers

When the onCreate() method returns, your local variable will be cleaned up from the stack, so they won't exist anymore. But the anonymous class object new View.OnClickListener() references these variables. Of cause it's wrong behavior so java don't allow you to do this.

After it is final it becomes a constant. So it is storing in the heap and can be safely used in anonymous classes.

like image 157
amukhachov Avatar answered Sep 22 '22 05:09

amukhachov


Your anonymous inner class refers to its enclosing scope by taking copies of the local variables - if you want to change the value of an int in an anonymous inner class, you need to do some hackery:

final int[] arr = new int[1];
arr[0] = 10;
Button button = (Button)findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener() {
  arr[0]++;
}
like image 36
hrnt Avatar answered Sep 21 '22 05:09

hrnt