最后的局部变量可能没有在匿名内部类初始化(Final Local Variable may not have been initialized in anonymous inner class)

这里是我的代码:

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

(有实际功能的名称)

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

Java是给我如何myFoo可能尚未初始化错误。 有没有什么办法解决这一问题? 我可以潜在地设置回调,当我构造对象,然后再把它更改为空,但我希望那里是一个更清洁的方式。 有任何想法吗? (也即是行不通的,如果美孚不是我写的,并没有公开接口以后更改回调)

如果有人想了解情况,在我的具体情况,foo是一个ArrayAdapter,酒吧是notifyDataSetChanged()。 什么是适配器显示依赖于数组元素的值,并且点击时,他们的价值观发生改变。 回调是clickListener。

Answer 1:

简短的回答是,你绝对不能做,在Java中,但编译器已经告诉你这一点。 你想在与相互之间的引用一旦创建两个对象,这是一个鸡和蛋的问题。 底线是,你必须首先创建其中之一。

一个建议是两个步骤创建:

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

然后“初始化”方法添加到适配器。

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

因为建筑是有些复杂(也就是说,不是简单地调用构造更复杂),我建议你再拉动到这两条线MyArrayAdapter工厂方法,并且使构造私有。



Answer 2:

这将在一般和没有获得工作Inner定义,但你需要创建一个辅助类:

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

然后用它是这样的:

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


Answer 3:

你可以声明一个方法callBarOnMyFoo包含类和回调调用它:

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

然后您的回调需要调用callBarOnMyFoo ,这是外部类,其中的一个实例方法Inner的代码应该有一个参考(我忘了语法它副手)。