2011-06-30 48 views
7

如何访问外部类的字段,给定对内部类的对象的引用?外部类的访问字段

class Outer 
{ 
    int field; 

    class Inner 
    { 
     void method(Inner parameter) 
     { 
      // working on the current instance is easy :) 
      field = 0; 
      Outer.this.field = 1; 

      // working on another instance is hard :(
      parameter.field = 2;    // does not compile 
      parameter.Outer.this.field = 3; // does not compile 
      parameter.outer().field = 4;  // This works... 
     } 

     // ...but I really don't want to have to write this method! 
     Outer outer() 
     { 
      return Outer.this; 
     } 
    } 
} 

我也试过Outer.parameter.field和许多其他变种。有没有一种语法可以做我想要的?

+0

不是一个内部类被用来只是其外部类中的目的是什么? – Heisenbug

+0

我认为这是做到这一点的方法。如果你觉得这是错误的,也许你可以考虑重构或以不同的方式构建这些类。 – Luciano

+5

我不知道有任何其他的方式来做到这一点,但我会说,如果你必须这样做扭曲,通常意味着你应该重新考虑设计。 –

回答

2

有两种方法可以查看您在做什么,作为静态方法或作为非静态方法。

乍一看,您的示例看起来更像是一个静态方法,因为它操纵参数的状态而不是它自己的状态。之前已经讨论了静态问题,例如请参阅In Java, how do I access the outer class when I'm not in the inner class?

但是,您的示例是一种非静态方法,我想我会看到您获得的内容以及为什么您认为应该可以使用外部引用。毕竟,在其他情况下,您可以访问您自己类型的其他实例的实现细节 - 例如,在重写equals时通常引用输入参数的私有成员字段。不幸的是,我只是不认为java提供了一种方法来引用另一个词法封闭的实例。这可能与the way that java actually implements non-static inner classes有关。 Java使用this$0用于自己的目的,但您无权访问此综合字段。

8

从内部类的外部,我相信在引用内部类实例的情况下,无法引用外部类实例的成员。从非静态内部类中,当然可以使用Outer.this.*语法引用它们。

想想这样:内部类实际上是一个完全独立的类。它有一个编译器生成的字段(通常命名为this$0)。在内部类中,该语言允许您使用Outer.this来引用该字段;但是,语法糖在内部阶层本身之外是不可用的。编译器生成的字段也不是。

8

这个怎么样的解决方案:

class Outer 
{ 
    int field; 

    class Inner 
    { 
     final Outer outer = Outer.this; 
     void method(Inner parameter) 
     { 
      // working on the current instance is easy :) 
      field = 0; 
      Outer.this.field = 1; 

      // working on another instance: 
      parameter.outer.field = 2; 
     } 
    } 
} 
+0

这就是我总是这样做的,虽然我会选择一个非您的示例的原始字段。只存储对父范围的引用并通过它访问字段可避免在对象而不是基元时使用“field”的陈旧引用,这是此方法的主要优点。 – KomodoDave