所谓 基础不牢地动山摇,又所谓经济基础决定上层建筑…扯偏了
说一说没有指针的java 语言 对象在内存中是如何存储的吧
java内存分配,详见 java内存分配
首先:
一个对象内存图
方法区是存储 .class相关信息,所以在你运行main方法之前,方法区最先有数据
我们看左边一共有几个.class ?可以看到是有两个class,一个Phone,一个Demo01…
之后,程序以main方法为入口,所以 main 方法先执行,将main方法压入栈底,
main方法中定义了 对象名称,实际上,对象名称就好比局部变量,所以也是存在栈中的
引用后面 new 了一个实体对象,我们在堆中开辟一段空间来存放 Phone对象,好吧,既然创建了Phone对象,那么Phone对象中都有什么呢,我们在方法区中找,将成员变量对应拿过来,再给他们赋上一些默认值
通过之前的讲解我们知道,凡是在堆中的数据都有默认值,由于Phone对象的成员变量没有手动初始化,于是这里Phone对象的成员变量也不例外
成员变量完成了,成员方法呢? 对于一个对象来说,它的成员方法实际上保存的是一个地址值,所以我们将.class 中 Phone对象中的地址值,保存在堆当中
当我们将对象赋值给引用的 时候,实际上就是将引用指向我们对象的地址
接下来,我们给成员变量赋值,通过 one.属性,通过one我们能找到堆中对应的对象地址,之后 为成员变量赋值
接下来 我们调用了 call 方法,首先,我们通过one 找到堆中对应的对象,第二步,Phone对象再根据保存的方法地址,再去方法区中找到相应的方法,然后入栈,执行,然后出栈
接着main方法继续执行,调用第二个成员方法,第二个方法 sendMessage 也执行相应的步骤,
最后,main方法执行完毕,出栈
总结:既然是栈,必然是线性执行的
两个对象使用同一个方法
好吧,讲完了第一种,对象内存图,第二种似乎就显而易见了
每new 一个对象,我们都要在堆中开辟新的空间,
而相同对象的成员变量,我们参考方法区中的Phone.class将相应的成员变量拿过来,
而相同的成员方法保存的则是 Phone.class中的成员方法的地址
两个引用指向同一个对象
第三种方式,相对比较简单,参考前两种内存图原理,这里不再赘述