static修饰符与可见性无关,所以什么都不会改变。您不能从不同的包访问受保护的成员(即字段、方法),无论它是否是静态的。
但在您的情况下,MyClass2 扩展了 MyClass1。您可以从超类访问受保护的成员。不过,静态与此无关。
编辑:
嗯,这是一个非常有趣的案例,因为涉及到两个不同的事情:1)从不同包中的子类访问受保护的成员,2)允许您访问静态(类)成员(如实例成员)的语法技巧。
我将扩展您的示例以显示您在此代码中实际执行的操作:
package p1;
public class MyClass1 {
protected String protectedString = "example";
protected static String protectedStaticString = "example";
}
package p2;
import p1.MyClass1;
public class MyClass2 extends MyClass1 {
public void testProtected() {
MyClass1 otherMC1 = new MyClass1();
MyClass2 otherMC2 = new MyClass2();
String testProtected;
testProtected = this.protectedString; // OK, protectedString is inherited, so it's instance member of this class
testProtected = super.protectedString; // OK, it's also instance member of superclass
testProtected = otherMC1.protectedString; // ERROR. You can't access protected members of other instance of superclass
testProtected = otherMC2.protectedString; // OK. As it's inherited member of MyClass2, you can access it if it belongs to other instance of your class
}
public void testProtectedStatic() {
MyClass1 otherMC1 = new MyClass1();
MyClass2 otherMC2 = new MyClass2();
String testProtectedStatic;
testProtectedStatic = this.protectedStaticString; // OK - syntax trick
testProtectedStatic = super.protectedStaticString; // OK - syntax trick
testProtectedStatic = otherMC1.protectedStaticString; // OK - syntax trick
testProtectedStatic = otherMC2.protectedStaticString; // OK - syntax trick
testProtectedStatic = MyClass1.protectedStaticString; // OK - you can access protected static members from superclass
testProtectedStatic = MyClass2.protectedStaticString; // OK - this also static member of your class
}
}
现在,什么是“语法技巧”。编译器允许您像访问实例成员一样访问静态成员:
MyClass mc = new MyClass();
Object o = mc.STATIC_FIELD;
但是实际上将编译为字节码的内容:
MyClass mc = new MyClass();
Object o = MyClass.STATIC_FIELD;
以这种方式访问静态成员被认为是不好的做法,因为它具有误导性。您应该始终以静态方式访问静态成员,以避免在阅读代码时产生混淆。
这就是你的情况。有静态字段以非静态方式访问,所以它看起来像实例字段。当您删除静态修饰符时,它成为实例成员。访问此字段的方式发生了变化,但由于您的object.staticField语法,您没有注意到这一点。