为什么受保护的静态字段在Java中的不同类中可见



这里有以下代码:

package ab:
public class A {
    protected static int var = 10;
    protected int var2 = 20;
}

    package cd;
    public class C extends A {
        A test;
        public C(){
            test = new A();
        }
        void printValues(){
            System.out.println(A.var); //this is perfectly visible
            System.out.println(test.var2); // here I get error saying var2 is not visible
        }
    }

我不明白为什么静态保护字段可以通过不同包中的A访问。。。

由于protected成员可以从任何包中的子类访问这一事实大家都很熟悉,所以我回答您的另一个问题:为什么protected实例字段对子类不可见?

和往常一样,寻找权威答案的地方是Java语言规范,在本例中是第6.6.2节。我引用那里的例子是因为它比前面的法律术语更容易理解

TL;DR:最好的方法是:protected继承的内部类。从其所有子类的角度来看,A.var2的行为类似于私有成员,每个子类单独,而不是超类的成员。所有这一切都到位了,因为protected旨在用于为扩展设计的类中,这样子类就可以访问那些被视为扩展类的公共API的部分,而不是该类的客户端。

为了完成你的一系列例子,我再提交两个:

System.out.println(this.var2);      // works---intended use of protected
System.out.println(((A)this).var2); // fails same as your test.var2

思考的食物:)

示例6.6.2-1。访问受保护的字段、方法和构造函数

考虑这个例子,其中points包声明:

package points;
public class Point {
  protected int x, y;
  void warp(threePoint.Point3d a) {
    if (a.z > 0)  // compile-time error: cannot access a.z
      a.delta(this);
  }
}

threePoint包声明:

package threePoint;
import points.Point;
public class Point3d extends Point {
  protected int z;
  public void delta(Point p) {
    p.x += this.x;  // compile-time error: cannot access p.x
    p.y += this.y;  // compile-time error: cannot access p.y
  }
  public void delta3d(Point3d q) {
    q.x += this.x;
    q.y += this.y;
    q.z += this.z;
  }
}

方法delta在这里发生了编译时错误:它不能访问其参数p的受保护成员xy,因为Point3d(对字段xy进行引用的类)是Point(声明xy的类)的子类,它不涉及CCD_ 17(参数CCD_。方法delta3d可以访问其参数q的受保护成员,因为类Point3dPoint的子类并且涉及Point3d的实现。

方法delta可以尝试将其参数强制转换(§5.5,§15.16)为Point3d,但如果运行时p的类不是Point3d,则此强制转换将失败,从而导致异常。

方法warp中也会出现编译时错误:它无法访问其参数a的受保护成员z,因为尽管类Point(对字段z进行引用的类)参与了Point3d(参数a的类型)的实现,但它不是Point3d(声明z的类)的子类。

受保护意味着所有子类以及同一包中的所有其他类都可以访问它。在这种情况下,CA的子类,因此可以访问字段,而不管它在哪个包中

不过,子类C不能访问任何其他A对象的受保护字段,只能访问C对象。因此,它可以访问this.var2,如果您将A test;更改为C test;(并将初始化更改为test = new C();,则可以访问它。

最新更新