Java中通过对象访问protected成员的权限疑问
解开Java Protected成员访问的困惑
嘿,我之前也踩过这个protected权限的坑,太懂你这种“明明规则说子类和同包能访问,怎么用对象调用就报错”的疑惑了!其实问题出在大家对protected的规则理解不够细致——它不是简单的“子类/同包就能随便访问”,还要看你访问的方式和被访问对象的实际类型。
先给你拆解清楚核心规则:
- 同包场景:不管是不是子类,同包内的任何类都能直接访问该包内类的protected成员,包括通过对象调用,这个是没问题的。
- 子类场景:这里分两种情况,很容易踩坑:
- 如果是子类自己的实例(比如用
this或者直接调用继承来的成员),完全可以访问,这是继承带来的权限。 - 如果是父类的对象(哪怕你用子类引用指向它),或者是子类对象但在子类外部的代码中访问,这时候就会受限——除非子类和父类在同一个包。
- 如果是子类自己的实例(比如用
结合你的包结构(根包javaapplication1下有entities和newpackage两个子包),我给你举具体代码例子,一看就明白:
示例代码
父类(在javaapplication1.entities包)
package javaapplication1.entities; public class Parent { protected String protectedField = "我是protected成员"; }
子类(在javaapplication1.newpackage包)
package javaapplication1.newpackage; import javaapplication1.entities.Parent; public class Child extends Parent { public void testAccess() { // 1. 访问自身继承的protected成员:正常运行 System.out.println(this.protectedField); // 2. 创建父类对象并访问其protected成员:编译报错! Parent parentObj = new Parent(); // System.out.println(parentObj.protectedField); // 这行会报错 // 3. 创建子类对象并访问其protected成员:正常运行 Child childObj = new Child(); System.out.println(childObj.protectedField); } }
同包的普通类(在javaapplication1.entities包)
package javaapplication1.entities; import javaapplication1.newpackage.Child; public class SamePackageClass { public void testAccess() { // 访问父类对象的protected成员:正常(同包) Parent parentObj = new Parent(); System.out.println(parentObj.protectedField); // 访问子类对象的protected成员:正常(同包) Child childObj = new Child(); System.out.println(childObj.protectedField); } }
不同包的非子类(在javaapplication1.newpackage包)
package javaapplication1.newpackage; import javaapplication1.entities.Parent; public class NonChildClass { public void testAccess() { // 访问父类对象的protected成员:报错(不同包且非子类) Parent parentObj = new Parent(); // System.out.println(parentObj.protectedField); // 访问子类对象的protected成员:报错(不同包且非子类) Child childObj = new Child(); // System.out.println(childObj.protectedField); } }
总结一下关键逻辑
protected权限的核心是:看「访问代码所在的类」和「被访问对象所属的类」之间的关系,而不是只看访问类是不是子类:
- 若访问类和被访问对象的类同包:无限制,随便访问。
- 若访问类是被访问对象的类的子类:
- 只能访问自身实例或子类实例的protected成员(因为这些成员是子类继承来的);
- 不能直接访问父类实例的protected成员(除非同包)。
这样是不是就清楚为什么你用对象调用会出现异常情况了?本质是没搞清楚protected权限的上下文限制~
内容的提问来源于stack exchange,提问作者Jtx
相关产品推荐
相关产品推荐

