Java继承底层原理:子类到底继承了父类的什么?private成员也能继承?
子类能调用父类的private成员变量吗不能。那private变量到底有没有被继承很多人会答错。今天这篇文章从内存层面把Java继承的底层原理讲清楚包括不同成员的继承规则、虚方法表机制、内存分配逻辑。一、继承的核心误区能调用不等于能继承很多人用“爸爸的钱儿子能用就是继承”来理解继承这是错的。真正的继承是父类有的子类也有一份。能调用只是子类没有时可以使用父类的内容。正确类比父亲会武功儿子也学会拥有这份武功才是继承。二、不同成员继承规则不同成员类型能否被继承能否直接调用说明构造方法❌ 不能✅ 能通过super名称必须同类名成员变量✅ 能非私有✅ 私有❌private变量也能继承只是不能直接调用虚方法✅ 能✅ 能非final、非static、非private的普通方法final方法❌ 不能✅ 能不能重写static方法❌ 不能✅ 能属于类private方法❌ 不能❌ 不能完全隔离重点private成员变量也能被子类继承只是无法直接访问需要通过父类提供的get/set方法操作。三、继承结构的内存分配类加载顺序创建子类对象时先加载父类字节码再加载子类字节码。多级继承从顶级父类Object开始逐级加载。堆内存对象结构用new创建子类对象时堆中的对象空间会被一分为二左侧存储从父类继承过来的成员变量右侧存储子类独有的成员变量所有属性先完成默认初始化再依次赋值。示例class Person { private String name; private int age; } class Student extends Person { String grade; } // 创建对象 Student stu new Student(); stu.name 小丹丹; // 给父类继承来的name赋值 stu.age 19; // 给父类继承来的age赋值 stu.grade 二年级; // 给子类自己的grade赋值堆中Student对象包含三块数据name、age、grade。private修饰的name和age确实在对象里只是子类不能直接访问。四、虚方法和虚方法表虚方法非final、非static、非private修饰的普通成员方法。日常开发中大部分方法都是虚方法。虚方法表机制每个类都维护一张虚方法表存储本类所有虚方法的内存地址。继承时子类会复制父类的虚方法表然后在表末尾添加自己的虚方法。重写的本质子类重写父类虚方法时替换虚方法表中对应方法的地址。调用时直接查表取地址不需要遍历继承链。Object类有几个虚方法Object类中共有5个虚方法clone()、equals()、hashCode()、notify()、toString()。getClass()、wait()等方法被final修饰不是虚方法。五、final和static方法的调用原理final方法编译期编译器遍历继承链确定方法所在类记录地址运行期直接执行编译期确定的方法static方法编译期编译器遍历继承链确定方法所在类后自动将对象调用转为类名调用运行期直接执行建议直接用类名.方法名()调用静态方法避免编译器额外转换提升效率。六、虚方法表设计思想空间换时间虚方法调用频率极高。如果每次调用都遍历继承链查找性能会很差。虚方法表用少量额外内存存储所有虚方法地址调用时直接查表大幅提升运行效率。现代计算机内存充足牺牲少量空间换运行效率性价比极高。七、知识点总结概念核心要点继承本质子类拥有父类成员的副本而非仅能调用private变量能被继承但不能直接访问类加载顺序先父类后子类多级继承从Object开始堆对象结构父类属性和子类属性分开存储虚方法非final、非static、非private的普通方法虚方法表存储虚方法地址子类继承后添加自己的虚方法重写本质替换虚方法表中的方法地址设计思想空间换时间牺牲内存换运行效率