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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© amen0205 中级黑马   /  2013-3-2 01:16  /  2575 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 门文通 于 2013-3-2 22:32 编辑

String ss="abc";
如果在字符串池中有字符串”abc“ 则把ss指向即可,如无,则先创建字符串”abc“,再赋值给ss。

我就想问  字符串池在哪里?  栈中吗?  还是堆中?  
我想不应该是堆中,因为如果好多字符串如果没有被指向的话  估计早就被垃圾回收机制回收了,那下次需要还要重新建立,很麻烦。
知道的大哥给解释下吧  尽量详细点

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 神马都是浮云

查看全部评分

6 个回复

倒序浏览
字符串池属于常量池的一部分,在栈中分配。
由于字符串对象的大量使用(它是一个对象,一般而言对象总是在堆中分配内存),Java中为了节省内存空间和运行时间(如比较字符串时,==比equals()快),在编译阶段就把所有的字符串文字放到一个字符串池中,而运行时字符串池成为常量池的一部分。字符串池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。

创建字符串有两种方式:两种内存区域(字符串池,堆)
1," " 引号创建的字符串在字符串池中
2,new,new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址(注意,此时不需要从堆中复制到池中,否则导致浪费池的空间)

另外,对字符串进行赋值时,如果右操作数含有一个或一个以上的字符串引用时,则在堆中再建立一个字符串对象,返回引用;如
String str1 ="def";            1
String str2=str1+ "abc";     2
这里的“def”和“abc”都在常量池,当运行第二句的时候,str2在堆内存中创建一个对象,因为右边str1是引用。  
比较两个已经存在于字符串池中字符串对象可以用"=="进行,拥有比equals操作符更快的速度。

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

回复 使用道具 举报
字符串池即StirngPool的确是存在于常量池中,其实字符串池只是常量池的一部分,那些常量如final修饰的常量也存在常量池中;我记得毕老师说过,常量池是存在于方法区中的。java为了优化内存空间,将那些固定不变的作为常量存储起来,并不会再第二次创建相同的常量了,即所说的创建了String s = "abc",在定义String b = "abc"就会将变量b也指向已有的"abc"了。其中a和b这两个变量是存在于栈内存中的,使用完毕就会释放的。而"abc"是存在于常量池中,常量池存在于方法区中,所以,使用完后,还是存在这个常量的。因此,常量池不是在栈内存中,而是单独的开辟的方法区中。其实,这些常量是在jvm在加载class之后,才在方法区中开辟的一片空间的。
如果感兴趣的话,你可以看看关于内存分配的总结:

java内存管理详细介绍.zip

61.89 KB, 下载次数: 162

评分

参与人数 1技术分 +1 黑马币 +9 收起 理由
李培根 + 1 + 9 很给力!

查看全部评分

回复 使用道具 举报
java内存出了堆,栈还有个方法区,也叫共享区,就是用来存放常量,静态成员的,String缓冲池也在里面,
如果通过String str="abc"这种方试直接创建字符串,它不会在堆内存中直接创建
而是查看常量池中是否存在"abc"
如果存在就返回该常量的引用,
不存在的话就在常量池中心创建一个在返回引用
回复 使用道具 举报
李志卫 发表于 2013-3-2 02:14
字符串池属于常量池的一部分,在栈中分配。
由于字符串对象的大量使用(它是一个对象,一般而言对象总是在堆 ...

很详细  谢谢
回复 使用道具 举报
现在才发现,很有帮助,相见恨晚啊
回复 使用道具 举报
我也..刚玉到
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马