有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java最终局部变量可能尚未在匿名内部类中初始化

这是我的密码:

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,而条是notifyDataSetChanged()。适配器显示的内容取决于数组中项目的值,这些值在单击时会更改。回调是clickListener


共 (3) 个答案

  1. # 1 楼答案

    这将在一般情况下工作,并且无需访问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 );
    
  2. # 2 楼答案

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

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

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

  3. # 3 楼答案

    简单的回答是,在Java中绝对不能这样做,但编译器已经告诉过你了。如果您试图同时创建两个相互引用的对象,这是一个鸡和蛋的问题。总之,您必须首先创建其中一个

    建议分为两步创建:

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

    然后将“initialize”方法添加到适配器

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

    因为这种构造有点复杂(也就是说,比简单地调用构造函数更复杂),所以我建议将这两行代码拉入MyArrayAdapter工厂方法,并将构造函数设为私有