为什么受保护的静态字段在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在不同的包中访问…

最佳答案
由于受保护的成员可以从任何包中的子类访问这一事实已经广为人知,因此我回答了问题的另一面:为什么受保护的实例字段对子类不可见?

像往常一样,寻找权威答案的地方是Java语言规范,在这种情况下是Section 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

深思熟虑:)

Example 6.6.2-1. Access to protected Fields, Methods, and Constructors

Consider this example, where the points package declares:

06001

and the threePoint package declares:

06002

A compile-time error occurs in the method delta here: it cannot access the protected members x and y of its parameter p, because while Point3d (the class in which the references to fields x and y occur) is a subclass of Point (the class in which x and y are declared), it is not involved in the implementation of a Point (the type of the parameter p). The method delta3d can access the protected members of its parameter q, because the class Point3d is a subclass of Point and is involved in the implementation of a Point3d.

The method delta could try to cast (§5.5, §15.16) its parameter to be a Point3d, but this cast would fail, causing an exception, if the class of p at run time were not Point3d.

A compile-time error also occurs in the method warp: it cannot access the protected member z of its parameter a, because while the class Point (the class in which the reference to field z occurs) is involved in the implementation of a Point3d (the type of the parameter a), it is not a subclass of Point3d (the class in which z is declared).

转载注明原文:为什么受保护的静态字段在Java中的不同类中是可见的 - 代码日志