简体   繁体   中英

Why protected static fields are visible from different class in Java

Here is the following code:

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

and

    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
        }
    }

I cannot understand why static protected field is accessible though A in different package...

Since the fact that a protected member is accessible from a subclass in any package is widely familiar, I am answering the flip side of your question: Why is the protected instance field not visible to the subclass?

As usual, the place to look for the authoritative answer is the Java Language Specification, in this case Section 6.6.2 . I am quoting the example found there because it is much easier to follow than the legalese that precedes it.

TL;DR: The best way to think of it is this: protected is an inherited class internal . From the perspective of all its subclasses, A.var2 behaves like a private member of each subclass individually and not a member of the superclass. And all this is in place because protected is intended to be used in a class designed for extension, so that the subclasses can access those parts which are considered public API for the extending class, but not for the client of the class.

To complete your series of examples I submit two more:

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

Food for thought :)

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

Consider this example, where the points package declares:

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

and the threePoint package declares:

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

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).

Protected means that all subclasses get access to it, and all other classes in the same package. In this case, C is a subclass of A and thus get access to the fields, regardless of the package it is in.

The subclass C can't access a protected field of any other A object though, only of C objects. So it can access this.var2 , and if you change A test; into C test; (and the initialization into test = new C(); , you are able to access it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM