TestPerson类执行内存变化图[高淇Java065]

示例【4-4】Person类

public class Person {
    String name;
    int age;
    public void show(){
        System.out.println("姓名: " + name + ", 年龄:" + age);
    }
}

示例【4-5】TestPerson类

public class TestPerson {
    public static void main(String[] args){
        // 创建P1对象
        Person P1 = new Person();
        P1.age = 23;
        P1.name = "张三";
        P1.show();
        // 创建P2对象
        Person P2 = new Person();
        P2.age = 35;
        P2.name = "李四";
        P2.show();
    }
}

运行TestPerson的内存分析:
1、从TestPerson类开始运行,首先扫描到main方法,将mian()的栈帧进栈,其中存储了相关变量、返回值等。在main()中,也就是形参args,由于没有赋值,所以为空(null)。
2、然后创建变量P1(引用类型,4个字节),此时值为null(Person P1)。与此同时,运行到Person类,这个类的字节码文件就会加载到方法区中临时存储,如show方法。
请添加图片描述
3、然后调用了 new Person()方法,所以又会开启一个栈帧。
请添加图片描述
4、new Person()执行时,需要在堆中创建一个P1对象。p1对象创建好后,name默认为null,age为0,show方法不必在每个对象中都保存一边,直接将类信息里的show()地址赋给对象即可。然后将堆中P1对象的地址赋给main()中的P1变量即可。(2、3、4共同组成Person P1 = new Person()语句的内存变化)。运行完这行代码后,new Person()方法调用完成,将其栈帧出栈。

请添加图片描述
请添加图片描述
5、P1.age = 23;P1还是在main()方法中,直接根据地址执行,修改P1.age的值。*但是执行P1.name = “张三”;时,并不是直接把“张三”这个字符串直接放在对象所在的堆中,因为字符串在程序编译完之后就已经存储在常量池中了。*所以运行到此时,是将“张三”在常量池中的地址赋给了P1.name.请添加图片描述
6、P1.show()是个方法,所以需要重新开启一个方法栈帧。虽然没有显示参数,但是show()是含有隐式参数this的,所以栈帧中有参数this。运行完这行代码后,移除栈帧。请添加图片描述
请添加图片描述
7、然后创建P2对象,创建栈帧,同样的开始也是null。在堆中创建一个新的对象,与P1对象不同,但是结构相同。创建完成后移除栈帧。以相同的方式运行完P2.name。请添加图片描述
请添加图片描述
8、最后执行P2.show(),同样的,也需要创建栈帧。结束后删除栈帧。请添加图片描述
请添加图片描述
9、最后一行代码运行完成后,main()方法也运行完了,删除main()的栈帧。然后整个过程结束,整个堆空间和方法区也删除。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值