有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在静态工厂方法中使用重写方法创建实例时,如何访问封闭类中的私有字段?

我不确定这里发生了什么。导致错误的行位于打印机类型的对象的实现内部,该对象具有名为“string”的字段。整个过程都包含在名为“Printer”的抽象类中。如何在保持“字符串”字段私有的同时实现我想要的

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();
  }

}

共 (1) 个答案

  1. # 1 楼答案

    你可以说:

    System.out.println(super.string);
    

    问题是私有成员不是由子类继承的,尽管它们可以在声明私有成员的顶级类的整个主体中访问。因此,来自编译器的错误消息令人困惑(可能会说“错”)

    参见JLS 6.6.1关于可访问性:

    Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

    这里就是这种情况,因为您是从Printer的主体中访问私有成员的,该主体包含声明

    但是JLS section 8.2 "class members"有关于继承的规则:

    Members of a class that are declared private are not inherited by subclasses of that class.

    所以不能说this.string,因为string字段不存在于Printer的匿名子类中,而printString方法所在的子类中

    通过显式地引用super(或在Hero's answer中使用类型转换),可以清楚地表明您不想访问子类中的字段,而是想从超类访问字段