The final local variable may not have been initialized in the anonymous inner class

Here is my code:

final Foo myFoo = new Foo(new Inner() { @Override callback(){ myFoo.bar(); } }); 

(with actual function names)

 final MyArrayAdapter aa = new MyArrayAdapter(new View.OnClickListener() { @Override onClick(){ aa.notifyDataSetChanged(); } }); 

Java gives me an error about how myFoo cannot be initialized. Is there any way to fix this? I can potentially set the callback to null when I create the object and then change it afterwards, but I hope there will be a cleaner way. Any ideas? (And this will not work if Foo was not written by me and did not provide an interface for changing the callback later)

In case anyone is interested, in my particular scenario, Foo is an ArrayAdapter, and the panel is notifyDataSetChanged (). What the adapter displays depends on the values ​​of the elements in the array, and these values ​​change when clicked. The callback is a clickListener.

+7
source share
3 answers

Short answer: you definitely cannot do this in Java, but the compiler already told you that. You are trying to create two objects at once with links to each other, this is a problem with a chicken and an egg. Bottom line, you must first create ONE of them.

The offer consists of two steps:

 .... final MyArrayAdapter aa = new MyArrayAdapter(); aa.initializeButtonClickListener(); .... 

and then add the "initialize" method to the adapter.

 public void initializeButtonClickListener(){ this.button.setOnClickListener(new View.OnClickListener() { @Override onClick(){ notifyDataSetChanged(); } }); } 

Since this construction is somewhat complicated (i.e. more complicated than just calling the constructor), I would recommend then pulling these two lines into the MyArrayAdapter factory method and making the constructor private.

+6
source

This will work in general and without access to the Inner definition, but you need to create a helper class:

 class CallbackHelper { private Foo foo; public void setFoo( Foo f ){ foo = f; } public Foo getFoo(){ return foo; } } 

And then use it like this:

 final CallbackHelper cbh = new CallbackHelper(); Foo myFoo = new Foo(new Inner() { @Override callback(){ cbh.getFoo().bar(); } }); cbh.setFoo( myFoo ); 
+3
source

You can declare the callBarOnMyFoo method in the containing class and call it from your callback:

 void callBarOnMyFoo() { myFoo.bar(); } 

Then your callback will need to call callBarOnMyFoo , which is the instance method of the outer class in which the Inner code must have a link (I forgot the syntax for it from hand to hand).

0
source

All Articles