Inner class non-final variable java

I needed to change the variables inside the inner class, and I got the notorious error "I can’t refer to a non-finite variable inside the inner class defined by another method."

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

I quickly created a class that had everything I wanted to change, and made the 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) { xq = i; } }); } 

This seems to be what I need and it works, but I am wondering if this is the right solution to the problem. Also, I really hate using the word temp to mean my class. Is there a real programming term for what I did to make a more descriptive name for my class?

+8
java inner-classes final local-variables
source share
4 answers

You can simply create an inner class instead of an anonymous one (for example, what you're doing now). Then you have the constructor and any other methods that you want to set for your participants. No hacking is required (for example, an array of 1 case).

I find this cleaner if the class requires some kind of data exchange with its outer class, but acknowledge that this is a personal preference. An array of 1 idioms will work as well and is shorter, but frankly, it just looks ugly. I usually restrict anonymous inner classes to those who simply 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 multiple threads are involved, then appropriate synchronization must also be used.

+9
source share

I posted a similar answer in another here . Basically, the idea is to create a “wrapper” that spans almost any type of Object . Since final in Java means “no reassignment” and not “permanent”, this trick is pretty much suitable. But, as mentioned in the original post, make sure you carefully execute it when used in a multi-threaded environment.

+2
source share

I would save the link to your click listener in an external class and make int a member variable in your listener. Just save the variable in the listener when you click, and then take the variable in the outer class when you need it, instead of setting it at the click point.

Simply put, if an inner class needs to change it, make it a variable in the inner class.

0
source share

Since you seem to be setting a few things (from the comments), create a method in the main class button1WasClicked() (the best name might be doUpdate, doSave, etc. - something that has something to do with what the button does) type there is the correct code and call it from the inner class / listener. (If you use Swing, I would do it Action, YMMV)

Thus, if a menu or intention or gesture appears later that needs to perform the same material, there is a call.

0
source share

All Articles