Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inner class non-final variable java

I needed to change variables inside an inner class and I got the infamous "Cannot refer to a non-final variable inside an inner class defined in a different method" error.

void onStart(){
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       int q = i;
     }
  });
}

I quickly made a class that held all of the things I wanted to change and made a final version of the class outside the inner class

class temp{
  int q;
}

void onStart(){
  final temp x = new temp();
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       x.q = i;
     }
  });
}

This seems to be what I need and it works but I am wondering if this is how to correctly work around the problem. Also, I really hate using the word temp to name my class. Is there an actual programming term for what I did so that I make a more descriptive name for my class?

like image 711
Aaron Greenberg Avatar asked Jul 03 '12 18:07

Aaron Greenberg


People also ask

Why local inner class cannot access non-final local variable?

Inner class object cannot use the local variables of the method in which the local inner class is defined. because use local variables of the method is the local variables of the method are kept on the stack and lost as soon as the method ends.

What is non-final variable in Java?

Using Java™ variables that are defined as static but not final can cause problems for Java routines. The reasons for those problems are: Use of variables that are static and non-final reduces portability.

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 local inner class access non-final local variables mcq?

A local class can only access local variables that are declared final in java.


1 Answers

You can simply create an inner class instead of an anonymous one (like you are currently doing). Then you have a constructor and any other methods you want to set your members. No hackiness required (like the array of 1 case).

I find this cleaner if the class requires any exchange of data with its outer class, but admit it is a personal preference. The array of 1 idiom will work as well and is more terse, but frankly, it just looks fugly. I typically limit anonymous inner classes to those that just perform actions without trying to update data in the outer class.

For example:

private MyListener listener = new MyListener();

void onStart(){
  bt.setOnClickListener(listener);
}

class MyListener implements OnClickListener
{ 
    String name;
    int value;

    void setName(String newName)
    {
        name = newName;
    }

    void setValue(int newValue)
    {
        value = newValue;
    }

    public void onClick(View v) 
    {
        // Use the data for some unknown purpose
    }
}

If there are multiple threads involved, then appropriate synchronization will have to be used as well.

like image 177
Robin Avatar answered Sep 23 '22 07:09

Robin