簡體   English   中英

在靜態工廠方法中使用覆蓋方法創建實例時,如何訪問封閉類中的私有字段?

[英]How can I access private field in enclosing class when creating instance with overridden method in static factory method?

我不確定這是怎么回事。 導致錯誤的行位於Printer類型的對象的實現中,該對象的名稱為'string'。 整個內容都包含在名為“打印機”的抽象類中。 如何在保持“字符串”字段私有的同時實現我想要的?

public abstract class Printer {

   static Printer blahPrinter(){
      Printer blahPrinter =  new Printer("blah") {
         @Override
         void printString() {
            System.out.println(this.string); //Here is the error: "string has private access in Printer"
         }
      };
      System.out.println(blahPrinter.string); //No error on this line
      return blahPrinter;
  }

  private final String string;  //Compiles and works as expected if I use a more visible access modifier

  public Printer(String string) {
     this.string = "I say " + string;
  }

  abstract void printString();

  public static void main(String[] args) {
     final Printer blahPrinter = Printer.blahPrinter();
     blahPrinter.printString();
  }

}

您可以通過以下方式解決此問題:

System.out.println(super.string);

事實是,私有成員不被子類繼承,盡管它們可以在聲明私有成員的頂級類的整個主體中訪問。 因此,來自編譯器的錯誤消息令人困惑(並且可能會說“錯誤”)。

有關可訪問性,請參見JLS 6.6.1

否則,如果將成員或構造函數聲明為私有,則僅當訪問發生在包含成員或構造函數的聲明的頂級類(第7.6節)的主體內時,才允許訪問。

在這種情況下,因為您是從Printer的主體內部訪問私有成員,該主體包含了聲明。

但是JLS第8.2節“類成員”具有繼承規則:

聲明為私有的類的成員不會被該類的子類繼承。

因此,您不能說this.string ,因為在您的printString方法所在的Printer的匿名子類中不存在該字段string

通過顯式引用super (或使用Hero回答中的類型轉換),您可以清楚地表明,您不想訪問子類中的字段,而希望訪問父類中的字段。

在您的匿名子類可以更換this.string通過((Printer) this).stringsuper.string

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM