A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 姚远 初级黑马   /  2012-5-11 05:40  /  2593 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

String str = "123";
请问 这个字符串"123"是存在栈区还是存在堆区?

10 个回复

正序浏览
孙峰 黑马帝 2012-5-11 10:16:43
10#
String对象的创建   关键是要明白其原理。

原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
  
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
  
原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
  
原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
"123"是对象,对象时存在Java 的堆空间里的。
变量才是在Java栈区
回复 使用道具 举报
田林 中级黑马 2012-5-11 09:30:38
8#
String str = "123";中的“123”存在于方法区中的常量池(constant pool)中的字符串(String pool)中。
String类对象初始化总结:
1.String s = “aaa”; (采用字面值方式赋值)

1) 查找String Pool  中是否存在“aaa ”这个对象,如果不存在,则在String Pool  中创建  一个“aaa ”对象,然后将String  Pool  中的这个“aaa ”对象的地址返回来,赋给引用变量s,这样s 会指向String Pool  中的这个“aaa ”字符串对象

2) 如果存在,则不创建任何对象,直接将String Pool 中的这个“aaa ”对象地址返回来, 赋给s 引用。

2. String s = new String(“aaa”);

1) 首先在String Pool  中查找有没有“aaa ”这个字符串对象,如果有,则不在String Pool  中再去创建“aaa ”这个对象了,直接在堆中(heap )中创建一个“aaa ”字符串对

   象,然后将堆中的这个“aaa ”对象的地址返回来,赋给s 引用,导致s 指向了堆中创建的这个“aaa ”字符串对象。

2) 如果没有,则首先在String Pool  中创建一个“aaa  “对象,然后再在堆中(heap)创建一个”aaa  “对象,然后将堆中的这个”aaa  “对象的地址返回来,赋给s  引用,

   导致s 指向了堆中所创建的这个”aaa  “对象。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
在堆中的缓冲区,但String str = "123";是否创建新对象取决于堆中的缓冲区是否已经存在了"123",
如果已经存在,则不创建对象,只是将引用指向已经存在的"123",否则就会new出一个新的对象"123"。
回复 使用道具 举报
String内存图解

String内存图解.png (25.91 KB, 下载次数: 65)

String内存图解.png
回复 使用道具 举报
字符串是常量,创建之后它们的值是不可以改变的,所以它们可以共享。字符串如果没有new对象,那么这个字符串是存在堆区中的一块区域叫缓冲区(常量池)。正如楼主提供的代码String str = "123";该语句在执行的时候,虚拟机会的常量池中是否存在"123"这个常量,如果不存在则在常量池中创建,下次再有String str1 = "123",那么str1不会再创建这个对象,直接指向常量池中已经存在的"123"。但是如果是String str = new String("123"),那会在堆内存创建一个"123"对象,并且也会在常量池中查看是否有该对象,如果有则不创建,如果没有则也会在常量池创建一个"123"。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
在堆中,而且是在堆的缓冲区中。
回复 使用道具 举报

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

堆里都是存储对象
栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)
回复 使用道具 举报
当然是堆区
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马