java的栈内存和堆内存_Java中的栈内存和堆内存

为什么我们常说基本类型传递的是具体的值,而对象传递的是对象的内存地址呢。要搞清楚这个问题就要搞清楚栈内存与堆内存。

java的内存分为栈内存和堆内存,两者的作用是不同的,我们可以简单的理解如下:

当我们创建一个java基本类型的变量时,只会用到栈内存而不会用到堆内存,栈内存中所存储的内容就是基本类型的值。

int a = 3;

int b = 3;

执行第一行 int a = 3;时,JVM先会创建一个变量为a的引用,然后在栈内存中查找是否已经存在3这个值,没有找到,就会在栈内存中开辟一片区域存储3,然后将a指向存储3的位置。接着执行第二行int b=3;时也是先在栈内存中查找是否已经存在3这个值,是可以找到的,这时就将变量b的引用也指向存储3的位置。

当我们用new来创建一个非基本类型的对象时,就不仅要用到栈内存还要用到堆内存。

例如,Student s=new Student();

也会先在栈内存中开辟一块内存,用s指向这块内存,但这时栈内存存储的不是new Student(),而只是一个内存地址,这个内存地址就是在堆内存中存储new Student()的那块内存的首地址。

有了上面的概念,就可以解决一些简单的问题了。

第一个,我们都知道比较字符串的内容要用到equals(),而不是==,原因是什么呢

String s1=new String(“abc”);

String s2=new String(“abc”);

s1==s2 的结果是false,原因很简单,因为第一行和第二行都用到了new来产生新的对象,这两个对象在堆内存中的首地址肯定是不同的,那么s1所指向的栈内存中的内容与s2所指向的栈内存中的内容肯定是不同的,而==

比较的是栈内存,这时肯定是不相等的。

而equals方法我们可以理解为比较的是堆内存中的内容,由于两个堆内存中的内容都是abc,则必然是相等的。

第二个,把上面的稍微换一下

String s1=“abc”;

String s2=“abc”;

这时s1==s2,因为没有new,也就没分配堆内存,都是用的是栈内存,在执行第二行时,栈内存中已经存在了abc,则s2直接指向这个地址就可以了,所以会有s1==s2。

第三个,执行 String s1=“hello”;s1=s1+“world”的结果是怎样的呢

执行第一句时,会在栈内存中分配一块内存存储hello,执行第二句时,会分配一块新的内存存储hello world,而这时的s1指向的不再是hello的那块内存而是hello world的那块内存了。存储hello 的那块内存将会被垃圾回收器所回收。

第四个,我们常说复制基本类型时传递的是具体的值,而复制对象时传递的是对象的内存地址,这时候如果将栈内存和堆内存理解了,就可以明白是为什么了。

补充:

String a="abc";

String b="abc";

String c=new String("abc");

String d=c.intern();

因为引用变量c指向堆内存的地址;但是intern(); 却在栈中开辟了一块内存;其实c.intern(); 执行时,在栈内存中发现存在对象“abc”,所以直接将指针指向“abc”,这样 a == d, b==d 结果为true;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值