7

这是我的代码:

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 可能没有被初始化的错误。有没有什么办法解决这一问题?我可以在构造对象时将回调设置为 null,然后再对其进行更改,但我希望有一种更简洁的方法。有任何想法吗?(如果 Foo 不是我写的并且没有公开接口以稍后更改回调,那么这也行不通)

如果有人好奇,在我的具体场景中,Foo 是一个 ArrayAdapter,而 bar 是 notifyDataSetChanged()。适配器显示的内容取决于数组中项目的值,并且这些值在单击时会发生变化。回调是 clickListener。

4

3 回答 3

7

简短的回答是你绝对不能在 Java 中这样做,但编译器已经告诉你了。您试图一次创建两个相互引用的对象,这是一个先有鸡还是先有蛋的问题。最重要的是,您必须首先创建其中一个。

建议是两步创建:

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

然后将'initialize'方法添加到适配器。

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

因为该构造有点复杂(即,比简单地调用构造函数更复杂),所以我建议将这两行拉入MyArrayAdapter工厂方法,并使构造函数私有。

于 2012-04-20T02:34:39.843 回答
3

这通常可以工作并且无需访问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 );
于 2012-04-20T02:37:14.897 回答
0

您可以在包含类中声明一个方法callBarOnMyFoo并从您的回调中调用它:

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

然后你的回调需要调用callBarOnMyFoo,它是外部类的一个实例方法,Inner代码应该引用它(我忘记了它的语法)。

于 2012-04-20T01:34:50.853 回答