Java继承中子类对象在堆中仅占一块连续内存,按继承链自上而下布局:对象头→父类字段→子类字段;静态成员存于方法区,与实例无关;字段静态绑定,方法动态绑定。

子类对象的堆内存是一整块
创建 new Child() 时,JVM 在堆中仅分配**一个对象实例**,其内存结构按继承链自上而下排布:
-
对象头(Object Header):位于最前端,含 Mark Word 和指向
Child.class元数据的指针(不是父类!) -
父类字段:紧随其后,按声明顺序存放根父类(如
Object)、中间父类(如Parent)的所有非静态字段 -
子类自身字段:排在最后,存放
Child类自己定义的非静态字段
例如:class A { int id; } → class B extends A { String name; },new B() 的堆布局就是:[Header][id][name]。字段通过固定偏移量直接访问,不查表、不跳转。
静态成员独立存在,不占对象空间
所有 static 变量、静态代码块、类元数据都加载到方法区(JDK8+ 是元空间),与对象实例无关:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先加载父类静态内容,再加载子类静态内容(顺序执行静态代码块)
- 静态变量属于类,不是某个对象;即使没创建任何对象,它们也已存在
- 子类能访问父类 public/protected 静态成员,但这是编译期绑定,不涉及运行时对象内存
构造过程是初始化,不是创建多个对象
调用 Child() 构造器时,并不会生成一个独立的 Parent 对象:
立即学习“Java免费学习笔记(深入)”;
- 父类构造器(
super())的作用是为当前子类对象中属于父类的那一段内存做初始化 - 字段赋值、代码块执行,都是在同一个堆内存块内完成的
- 即使父类是
abstract,只要被继承,它的字段仍会出现在子类对象内存中——抽象类不能实例化,但它的结构会被子类“吸收”
变量访问看编译类型,方法调用看运行类型
这解释了为什么向上转型后属性和方法行为不同:
-
字段(变量)是静态绑定:编译时就根据引用类型决定访问哪个字段。若
Parent p = new Child(); p.field,取的是Parent类中定义的field(哪怕Child也声明同名字段,那只是另一个独立字段) -
实例方法是动态绑定:运行时根据实际对象类型(
Child)查找方法表,执行子类重写版本 - private 字段虽不可见,但仍存在于子类对象内存中;可通过父类提供的 getter/setter 访问

















