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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 徐慧书 中级黑马   /  2012-5-1 13:42  /  3075 人查看  /  15 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

举例:String s1 = “abd”     String s2 = new String("efg");

我们知道,这里使用的String pool,jvm会去池中查找是否已经存在相同的串,存在则不创建,否则创之,那么 s2 通过new 是在stack中分配一块内存引用池中“efg”的首地址
疑问一: 是先在String pool中先寻找添加“efg”还是现在stack中先给s2分配内存呢?
疑问二: s1 = ”abd“  那么s1对象本身是存放在哪里呢? 又是怎么样的指向串"bd呢"?

15 个回复

倒序浏览
当我们直接对一个s1字符串创建引用的时候,会在常量池中创建一个字符串abd;当我们new一个String对象的时候会首先在常量池中查找,如果有的话就用,如果没有的话就在常量池宠创建一个对象,然后在把这个对象值付给堆内存中的String对象。
也就是说第一句是创建了一个对象,在常量池中;而第二个语句创建了2个对象,常量池中一个,对内存中一个。
哦了
看图


回复 使用道具 举报
隋丙跃 发表于 2012-5-1 13:58
当我们直接对一个s1字符串创建引用的时候,会在常量池中创建一个字符串abd;当我们new一个String对象的时候 ...

那么 String s1 = “abd” ;
String s2 = “abd”
会再池中建立建立一个"abd”串吧?
回复 使用道具 举报
那么 String s1 = “abd” ;
String s2 = “abd”
会再池中建立建立一个"abd”串吧?
回复 使用道具 举报
徐慧书 发表于 2012-5-1 14:03
那么 String s1 = “abd” ;
String s2 = “abd”
会再池中建立建立一个"abd”串吧? ...

是的,字符串都是一个常量,都在常量池中的
回复 使用道具 举报
楼上的说得对{:soso_e179:}
回复 使用道具 举报
常量池中专门开辟一块作为字符串存储,也可以说是字符串池。
回复 使用道具 举报
1. String s = “abd”; (采用字面值方式赋值)
  a   查找String Pool  中是否存在“aaa ”这个对象,如果不存在,则在String Pool  中创建一个“aaa ”对象,然后将String   Pool  中的这个“aaa ”对象的地址返回来,赋给引用变量s,这样s 会指向String Pool  中的这个“aaa ”字符串对象
  b   如果存在,则不创建任何对象,直接将String Pool 中的这个“aaa ”对象地址返回来,赋给s 引用。
2 . String s = new String(“efg”);
   a   首先在String Pool  中查找有没有“aaa ”这个字符串对象,如果有,则不在String Pool中再去创建“aaa ”这个对象了,直接在堆中(heap )中创建一个“aaa ”字符串对象,然后将堆中的这个“aaa ”对象的地址返回来,赋给s 引用,导致s 指向了堆中创建的这个“aaa ”字符串对象。
  b    如果没有,则首先在String Pool  中创建一个“aaa  “对象,然后再在堆中(heap)创建一个”aaa  “对象,然后将堆中的这个”aaa  “对象的地址返回来,赋给s 引用,导致s 指向了堆中所创建的这个”aaa  “对象。
回复 使用道具 举报
s1和s2位于栈内存中是引用型变量,它们只存放对象在内存中的地址。String s2 = new String("efg"),jvm会先在String pool中找有没有"efg",如果有就去堆内存中新建一个"efg"的副本,并把这个副本(对象)的地址赋给栈内存中的s2;如果没有就先在String pool在创建一个"efg",然后出堆内存中新建一个"efg"副本,在把这堆内存中的副本的地址赋给s2。
String s1 = “abd” ,s1是位于栈内存中是引用型变量,它存放的是 “abd” 在String pool中的地址,因为String s1 = “abd”并没有new对象,所以堆内存中并没有 “abd”的副本。
回复 使用道具 举报
崔仁军 发表于 2012-5-1 18:14
1. String s = “abd”; (采用字面值方式赋值)
  a   查找String Pool  中是否存在“aaa ”这个对象,如 ...

你这是复制来的吧,我都说是“abd”啦,你还aaa的,而且new 是在堆中存放副本而不是存放“abd”在pool中的地址噢
回复 使用道具 举报
永恒之翼网络 发表于 2012-5-1 18:55
s1和s2位于栈内存中是引用型变量,它们只存放对象在内存中的地址。String s2 = new String("efg"),jvm会先 ...

那请问,这个String pool 是在哪里开辟的空间,这个存储空间的大小等又有什么特殊的呢?
回复 使用道具 举报
隋丙跃 发表于 2012-5-1 13:58
当我们直接对一个s1字符串创建引用的时候,会在常量池中创建一个字符串abd;当我们new一个String对象的时候 ...

那请问,这个String pool 是在哪里开辟的空间,这个存储空间的大小等又有什么特殊的呢?
回复 使用道具 举报
马有失蹄人有失足的时候   听过这句没有    只不过最近敲代码头有点昏而已一时敲错了而已     你能找到第二个和我一样的吗     
回复 使用道具 举报
徐慧书 发表于 2012-5-1 21:19
那请问,这个String pool 是在哪里开辟的空间,这个存储空间的大小等又有什么特殊的呢? ...

常量池在方法区里面,方法区存储的就是一些代码啊,常量之类的,而堆里面只是引用,比如刚开始调用main方法,其方法体就是在方法区里面。这是目前我能掌握的,到后面可能还要细分,还没有学到那里呢
回复 使用道具 举报
徐慧书 发表于 2012-5-1 21:18
那请问,这个String pool 是在哪里开辟的空间,这个存储空间的大小等又有什么特殊的呢? ...

String pool的大小,这个不清楚,它是jvm设置的,就堆内存和栈内存,它们的空间不会超过系统为jvm分配的内存空间(默认分配为60M),因为String pool是jvm在系统分配给vm的空间里,划出来的一部分内存空间。String pool的特殊之处就是它的功能。它是为了节约内存空间而被创建出来的,因为在日常应用中会出现很多相同的字符串,但是它们又不是new String()出来的,为了节约内存空间,就相同的字符串作为一个字符串存放在String pool中,要用到时,去String pool中找。
回复 使用道具 举报

RE: 一个关于String 的问题

徐慧书 发表于 2012-5-1 21:18
那请问,这个String pool 是在哪里开辟的空间,这个存储空间的大小等又有什么特殊的呢? ...

String pool的大小,这个不清楚,它是由jvm设置的,就像堆内存和栈内存,它们的空间不会超过系统为jvm分配的内存空间(默认分配为60M),因为String pool是jvm在系统分配给jvm的空间里,划出来的一部分内存空间。String pool的特殊之处就是它的功能。它是为了节约内存空间而被创建出来的,因为在日常应用中会出现很多相同的字符串,但是它们又不是new String()出来的,为了节约内存空间,就把相同的字符串作为一个字符串存放在String pool中,要用到时,去String pool中找。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马