内存分析:super 与 this
- 一、绘制内存结构图
- 二、类加载
- 三、对象实例化
- 四、调用对象方法
根据以下父子类的定义调用代码,分析super与this关键字在内存中的执行过程
class Fu {
int num = 10;
public void method() {} // 父类方法
}
class Zi extends Fu {
int num = 20;
public void method() {} // 子类重写父类方法
public void show() {
int num = 30;
System.out.println(num); // 30
System.out.println(this.num); // 20
System.out.println(super.num); // 10
}
}
public class Demo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
zi.method();
}
}
一、绘制内存结构图
二、类加载
Fu类、Zi类、Demo类的字节码依次被加载到方法区。不同的是,子类在加载过程中会有一个 [[super_class]] 标记,这个标记指向父类,表示子类继承自父类
三、对象实例化
栈中开辟main方法栈帧,内部开辟名为zi的Zi类型变量,堆中实例化一个Zi类对象,由于Zi类是继承自Fu类的,实例化的Zi类对象内部会包含一个完整的Fu类对象,Fu类内容与Zi类内容之间相互隔离。JVM使用this指针指向子类内容,使用super指针指向父类内容。最后,将Zi类对象的地址赋值给栈空间的zi变量
四、调用对象方法
Zi类中的show()方法栈帧压栈,并在栈帧中定义一个num变量,进而依次执行:
- 打印方法本身栈帧中局部变量,根据this指针找到自身的成员变量并打印,
- 根据super指针找到Fu类的成员变量并打印。
- 最后,show()方法执行完毕,弹栈。
- 在Zi类的成员方法中找到Zi类的 method() 方法在方法区内的地址,将Zi类 method() 方法压栈
- 执行Zi类method方法时,内部有一个 super.method() 语句,根据super指针找到父类,在父类的成员方法中找到Fu类的method()方法在方法区中的地址,将Fu类method方法压栈
- Fu类method方法执行完毕后弹栈,回到Zi类method方法继续执行完毕后弹栈,
- 程序最后回到main方法继续执行完毕后弹栈,程序执行结束
图片内容源自B站黑马Java基础公开课