
java中继承对象在堆内存中只创建一个对象实例,其布局包含父类字段、子类字段及对象头,而非分别存储父类和子类两个独立对象。
在Java中,当执行 B b = new B(1, "b"); 时,JVM 不会 在堆中分别创建一个 A 实例和一个 B 实例;而是仅分配一块连续的内存空间来容纳整个 B 对象——该空间完整包含从根父类(如 Object)到最小子类(此处为 B)的所有非静态字段,按继承链顺序(父类字段在前,子类字段在后)紧凑排列,并附加统一的对象头(Object Header)。
以示例代码为例,B 对象在堆中的内存布局如下(忽略对齐填充):
+---------------------+ | Object Header | ← 引用 b 指向此处(即对象起始地址) +---------------------+ | int id (from A) | ← 父类字段,紧随对象头 +---------------------+ | String name (from B) | ← 子类字段,位于父类字段之后 +---------------------+
这种“扁平化字段布局”是Java实现单继承语义与多态基础的关键设计:
- 因为 B 的内存块天然“包含” A 的全部字段(且顺序一致),所以 B 引用可安全向上转型为 A(如 A a = b;),JVM 仅需将同一内存地址视为 A 类型指针即可;
- 字段访问通过固定偏移量完成:a.id 访问偏移量 8(假设对象头占8字节),b.name 访问偏移量 12,无需动态查找;
- 由于字段布局必须线性、唯一,Java 不支持多重继承(无法确定多个父类字段的排列优先级)。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 仅实例字段参与布局:静态字段(static)存储在方法区(JDK 8+ 为元空间),不占用对象实例内存;
- 构造过程 ≠ 内存分配:super(id) 调用的是父类构造逻辑,用于初始化已存在的 id 字段,而非新建父类对象;
- 内存对齐影响实际大小:JVM 可能插入填充字节(padding)确保字段对齐(如 long/double 对齐到8字节边界),因此实际对象大小可能大于字段总和;
- 继承深度无限制,但字段总数受类文件格式约束(最大65535个字段)。
简言之,Java 继承的本质是“扩展式内存封装”——子类对象是一块融合了所有祖先状态的单一内存单元,既保证类型安全,又保障运行时效率。理解这一机制,是掌握多态、序列化、反射及 JVM 调优的重要基础。










