java – 为什么受保护的实例成员在不同包中的子类中不可见,但受保护的类成员是?

参见英文答案 > Understanding java’s protected modifier                                    6个

package one;

public class A {
    protected int first;
    protected static int second;
}
package two;

import one.A;

public class B extends A {
    public void someMethod() {
        this.first = 5; //works as expected
        B.second = 6; //works
        A a = new A();
        // a.first = 7; does not compile

        //works just fine, but why?
        a.second = 8; 
        A.second = 9;
    }
}

为什么不对静态字段应用相同的限制,它背后的想法是什么?

最佳答案
JLS 6.6.2开始:

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

6.6.2.1开始:

Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.

this.first = 5;是因为B是A的实现者.

A.second有效,因为此限制仅为对象的成员定义. B.second也是如此.

至于为什么用这种方式指定,你必须要求定义规范的人 – 我们只能做出假设. 6.6.2.1甚至有一个表达类似问题的例子:

Consider this example, where the points package declares:

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

and the threePoint package declares:

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

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.


我建议退房Why we should not use protected static in Java.

受保护的语义以成员为目标 – 受保护的静态与受保护的目的相矛盾,这可能是它不受同样限制的原因.

转载注明原文:java – 为什么受保护的实例成员在不同包中的子类中不可见,但受保护的类成员是? - 代码日志