从嵌套的匿名类中引用匿名对象

时间:2012-01-02 16:11:32

标签: java this anonymous-class

是否可以做这样的事情(我使用初始化程序块来缩短示例)

new A() {{
  new B() {{
    method(outer.this);
  }}
}}

在哪里我提供外部对象的this作为第二个匿名类中方法调用的参数?我不能使用A.this,这会产生编译错误。

注意:给定的代码不能编译,它应该只说明我想要实现的目标。

编辑:更接近实际用例的示例:

public class Outer {

  public SomeBean createBean() {
    return new SomeBean() {

      private final Object reference = new SomeClass() {

        @Override
        public void notify() {
          Outer.callback(/*what goes here???*/);
        }
      };

      //Methods...
    };
  }

  public static void callback(final SomeBean bean) {
    // do stuff with bean
  }
}

我得到的编译错误就是我没有为回调提供正确的参数,因为我不知道如何引用SomeBean子类......

3 个答案:

答案 0 :(得分:2)

如果真的必须,我想这应该可行。

new A() {
    {
        new B() {{
            method();
        }};
    }
    private void method() {
        method(this);
    }
}

(历史记录:使用-target 1.3或更早版本,这应该是NPE。)

如果您不需要A内部类的确切类型。

new A() {
    {
        new B() {{
            method(a);
        }};
    }
    private A a() {
        return this;
    }
}

答案 1 :(得分:1)

@TomHawtin的答案很好,我的很相似。我会这样做:

new A() {
    private final A anon = this;
    /*init*/ {
        new B() {
            /*init*/ {
                method(anon);
            }
        }
    }
}

这可能会比调用一个方法来获得你的A实例提供稍微更好的性能。主要的好处是IMO更容易阅读/维护。

编辑: @Tomas的答案也非常相似,但是要求你在外部 - 外部类中保留对新A对象的引用,这可能不需要它。

根据操作编辑:

public SomeBean createBean() {
    SomeBean myBean = new SomeBean() {
        private final Object reference = new SomeClass() {
            @Override
            public void notify() {
                Outer.callback(/*what goes here???*/);
            }
        };
        //Methods...
    };
    return myBean;
}

FYI obj.notify()是Object中的最终方法,你无法覆盖它。 JavaDoc here

答案 2 :(得分:0)

考虑重构代码,因为您提出的代码似乎不太合乎逻辑,并且肯定不容易处理或保留。 你可以做一个非常相似的结构(继承两种不同类型并使用另一种类型),如下所示:

//declaring a variable as final enables accessing it from the B subtype if declared at the same scope (method)
final A myA=new A() {
   //personalized content for type A
};
//then, declare the B subtype, using the final myA var as you need, at the constructor 
B myB=new B() {{
   method(myA);
}};

如果您需要在暴露时覆盖两个类,请执行此操作。也许有一点反思可以让你从这些匿名课程中拯救你(或者至少从他们中的一些课程中拯救你)。

相关问题