2011-06-30 106 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