繁体   English   中英

我可以在外部类的构造函数中实例化一个匿名类吗?

[英]Can I instantiate an anonymous class in the constructor of outer class?

我有以下代码:

public class Outer {
     public Interface Anony {
         public void callback();
     }

     public Outer() {
        OtherClass.foo(new Anony() {
            @Override
            public void callback() {
                ....
            }
        });
    }
}

但是我的朋友告诉我,它有一些问题。 我在Outer的构造函数中创建了一个匿名类实例,因此匿名类实例隐式引用了外部类实例,即Outer.this。 但此时,外类实例还没有完全创建。 因此,匿名类实例引用具有不完整状态的对象,因此问题。

他是对的吗? 谢谢。

你的朋友是对的,但这取决于当然的用法。

问题不在于在构造函数中创建内部类。 如果内部类访问外部类,则会发生此问题。

这是因为任何对象都无法在构造函数中提供普通的被授权者。 对象操作所需的所有变量可能尚未初始化等。

但是如果内部类放在构造函数的末尾,我不会发现这个问题,但请记住,这是一个危险的开局,因为有人可能会修改代码,然后调试器的wtf时间...

可以做到,但你不应该这样做。

这是反模式的一个例子,它被称为“让this引用从构造函数中逃脱” - 将构造对象的引用传递给构造函数中的另一个类。 您不应该这样做的原因是,在多线程环境中,传递引用的类可能会看到新对象处于部分构造的状态,因此处于不一致状态。 这可能会导致奇怪且难以发现的错误。 IBM 撰写的这篇文章是众多描述它的文章之一。

不明显的是它是如何发生的:匿名类实际上是内部类,因此它们包含对包含类的引用(即this是构造的)。 收件人类OtherClass可以看到,并且在甚至做, this建设已完成之前。

我建立了一个脑力图...我能想到的所有不同可能性的例子:

class OtherClass
{
  public static void foo (final Anony x)
  {
    x.callback ();
  }
}

public class Outer
{
  public interface Anony
  {
    void callback ();
  }

  public class Inner implements Anony
  {
    public void callback ()
    {
      System.out.println ("Inner.callback");
    }
  }

  public class InnerDerived implements Anony
  {
    public void callback ()
    {
      System.out.println ("InnerDerived.callback");
    }
  }

  public static class StaticInner implements Anony
  {
    public void callback ()
    {
      System.out.println ("StaticInner.callback");
    }
  }

  public Outer ()
  {
    OtherClass.foo (new Anony ()
    {
      public void callback ()
      {
        System.out.println ("Anony.callback");
      }
    });
    OtherClass.foo (new Inner ());
    OtherClass.foo (new Inner ()
    {
      @Override
      public void callback ()
      {
        System.out.println ("Anony.Inner.callback");
      }
    });
    OtherClass.foo (new InnerDerived ());
    OtherClass.foo (new InnerDerived ()
    {
      @Override
      public void callback ()
      {
        System.out.println ("Anony.InnerDerived.callback");
      }
    });
    OtherClass.foo (new StaticInner ());
    OtherClass.foo (new StaticInner ()
    {
      @Override
      public void callback ()
      {
        System.out.println ("Anony.StaticInner.callback");
      }
    });
  }
}

预期产量应为:

Anony.callback
Inner.callback
Anony.Inner.callback
InnerDerived.callback
Anony.InnerDerived.callback
StaticInner.callback
Anony.StaticInner.callback

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM