子类对象内存中包含父类私有字段,只是编译期不可见;JVM为继承链分配连续内存,构造器通过super()初始化父类字段区域;访问需依赖父类public/protected方法或反射验证。

子类对象在内存中确实包含父类的私有字段,只是不能直接读写——这是理解隐式持有机制的关键。
私有字段物理存在,但不可见
Java中,private修饰符限制的是编译期的代码可见性,不是运行时的内存布局。当子类实例化时,JVM会为整个继承链分配连续内存空间:先初始化父类部分(含所有字段,无论private),再叠加子类新增字段。所以Student对象内部真实存储着父类定义的private String name和private int id,只是Student.java源码里任何地方都不能写this.name或this.id——编译器直接报错。
构造器调用是隐式持有的核心动作
子类构造器必须通过super()触发父类构造逻辑,这个过程把参数值写入当前对象所属的父类字段区域。例如:
- 父类Person(String n, int i)中this.name = n;实际是往“当前对象的父类内存段”赋值
- 子类Student(String n, int i, String major)调用super(n, i),等价于让父类代码操作本对象的私有字段
- 最终堆中只有一个对象,但字段按继承顺序排布:[name][id][major]
访问必须走父类提供的出口
子类要读取或修改这些隐式持有的私有字段,只能依赖父类暴露的public/protected方法:
立即学习“Java免费学习笔记(深入)”;
- 用super.getXXX()调用父类getter(如super.getName())
- 重写toString()时写super.toString()复用父类拼接逻辑
- 若父类没提供足够方法,应在父类中补充受控接口,而非降级为protected字段
验证隐式持有的典型方式
可通过以下手段确认私有字段确实在子类对象中:
- 打印对象toString()结果,若含父类私有字段值(如"Name: Alice, Age: 25"),说明已被初始化并存储
- 用Object.getClass().getDeclaredFields()反射获取全部字段(包括private),会列出父类字段
- 调试时观察对象内存视图,能看到父类字段与子类字段同属一个实例地址


















