
java中继承类的对象在堆内存中只占用一个连续对象空间,子类实例包含父类字段与自身字段的完整布局,通过对象头+父类字段+子类字段的顺序排列实现“is-a”关系。
在Java中,继承不意味着创建多个独立对象,而是通过单一内存块实现类型扩展。以如下代码为例:
public class A {
private int id;
public A(int id) { this.id = id; }
}
public class B extends A {
private String name;
public B(int id, String name) {
super(id);
this.name = name;
}
}当执行 B b = new B(1, "b"); 时,JVM在堆(Heap)中仅分配一个对象实例,其内存布局为:
- 对象头(Object Header):包含Mark Word(锁状态、GC分代年龄等)和Klass Pointer(指向Class元数据);
- 父类字段(inherited fields):按声明顺序依次存放A类的private int id(4字节,对齐后可能含填充);
- 子类字段(own fields):紧随其后存放B类的private String name(实际存储为String引用,即对象地址,通常8字节,64位JVM开启指针压缩时为4字节)。
✅ 这种扁平化、连续的字段布局是Java单继承语义的底层支撑:B实例的起始地址(即对象头地址)可直接被A类型引用安全使用——因为从该地址开始的内存区域,前部恰好符合A类的字段结构。这也是为什么 A aRef = new B(1, "b"); 合法且无需额外转换。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 字段内存顺序遵循继承链自顶向下 + 类内声明顺序,不受访问修饰符(private/public)影响;
- JVM可能插入填充字节(padding) 以满足内存对齐(如8字节边界),确保CPU高效访问;
- 父类构造器调用(super(id))仅负责初始化父类字段部分,并不创建独立A对象;
- 若存在多层继承(如 C extends B),字段将按 A → B → C 顺序线性展开,仍为单个对象。
总结:Java继承的本质是字段组合而非对象组合。理解这一内存模型,有助于深入掌握多态实现原理、序列化行为、以及Unsafe类字段偏移计算等高级主题。










