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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 朱晓盼 中级黑马   /  2014-4-17 10:13  /  2368 人查看  /  19 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

String s2 = new String("abc");
——————————————————————————
s2在内存中有两个对象,是说s2指向两个对象吗?那么这两个对象的内存地址值相同还是不同?在内存中是什么状态,最好画个图说明下,麻烦各位了,谢谢

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

19 个回复

倒序浏览
http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html
很详细,希望对你有帮助
回复 使用道具 举报
⒈心只霸占沵 发表于 2014-4-17 10:21
http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html
很详细,希望对你有帮助

谢谢,看过了,不过还有疑问,s2在内存中有两个对象,那么就是说s2指向两个对象,s2不可能存储两个地址值吧,或者是他们的内存地址值相同?那不就是一个对象了吗?
回复 使用道具 举报
s2指向的是一个对象啊    指向的是“abc”这个对象
回复 使用道具 举报
String类比较特殊,它有个字符串常量池,那篇博客中提到过。字符串常量池中相同字符串只能有一份,但new构造器的则不同,每次调用构造器,都在堆内存中创建一个字符串对象,无论字符串常量池是否存在该字符串。在堆内存中,相同的字符串可以存在多个。
这个题String s2 = new String("abc");
它会在堆内存中创建“abc”字符串,同时检查字符串常量池是否存在这个这符串,如果没有,将在字符串常量池创建这个字符串对象,两者的地址是不一样的。s2得到的是堆内存中字符串的地址。
String s = “abc”;这种方式创建时,创建的字符串常量存在于字符串常量池中,返回的是字符串常量池中字符串的地址。
回复 使用道具 举报
s2在创建之后,需要在堆内存中创建一个对象,也就是new一个对象,由于调用了String类的构造函数,往里传了一个“abc”,abc也是一个对象,传之前,先去字符串池寻找abc,找到了,就将对象的引用返回,没找到就创建对象将引用返回,因此,一个对象在堆中,一个对象在字符串池中
回复 使用道具 举报
本帖最后由 呆呆沙师妹 于 2014-4-17 11:05 编辑

你可以用下面这些代码试验一下,用intern() 方法可取出与堆内存中字符串相同的存在于字符串常量池中字符串的地址。它们地址是否相等用“==”判断即可
  1. String s = new String("abc");
  2. String s1 = "abc";
  3. String s2 = new String("abcabc");
  4. System.out.println( s1 == s );
  5. System.out.println( s1 == s.intern() );
  6. System.out.println( s2 == s2.intern() );
复制代码
回复 使用道具 举报
new String(String str)的源代码如下:
  1.     public String(String original) {
  2.         this.value = original.value;
  3.         this.hash = original.hash;
  4.     }
  5.   public int hashCode() {
  6.         int h = hash;
  7.         if (h == 0 && value.length > 0) {
  8.             char val[] = value;

  9.             for (int i = 0; i < value.length; i++) {
  10.                 h = 31 * h + val[i];
  11.             }
  12.             hash = h;
  13.         }
  14.         return h;
  15.     }
复制代码

首先==这个符号是什么意思要明白。当比较的是对象时,而不是进本数据类型时,==号比较的是地址值,而地址值不一定是hashCode值,因为hashCode被复写了就不是了,在Object类中地址值等于hashCode值。
在new对象时,需要在堆内存中分配空间,地址值是唯一的。这个要和“哈希表数据结构”分清楚。

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
Holy丶谢特  来自手机 初级黑马 2014-4-17 11:56:01
9#
应该是S2为一个对象,new string()为一个对象,且字符串abc存储于new string()对象中,然后将new string()在内存中的地址赋值给s2.
回复 使用道具 举报
⒈心只霸占沵 发表于 2014-4-17 10:49
s2指向的是一个对象啊    指向的是“abc”这个对象

那么new这个对象呢?s2不指向吗?那岂不是会被当做 垃圾回收了?
回复 使用道具 举报
朱晓盼 发表于 2014-4-17 12:08
那么new这个对象呢?s2不指向吗?那岂不是会被当做 垃圾回收了?

int a = 1;1会存放在栈里 String s1 = "thanks";thanks会存放在data segment里 String s2 = new String("thanks");thanks会存放在data segment里 String a ="th";String b = "anks";String c =a+b;c会存放在data segment里 字符串全部存放在data segment里 常量池全部在栈里。如果你不new的话,比如你写String s = "thanks";这时s分配在栈里,s直接指向字符池里的"thanks";但如果你这样写,String s; s = new String("thanks");这时s指向堆里的一块内存,这个内存里的地址指向字符池里的"thanks";

对内存是有会有机制的   栈内存没有自动回收机制
回复 使用道具 举报
呆呆沙师妹 发表于 2014-4-17 10:55
String类比较特殊,它有个字符串常量池,那篇博客中提到过。字符串常量池中相同字符串只能有一份,但new构 ...

你说的常量池中的字符串和堆内存中的字符串地址值不同,这个我懂,
但是我问的关键点不在这里
我想搞清楚,new出来的对象和“abc”这个对象在内存中是怎么存在的?
希望能给画张图,我觉得图画出来了,思想就出来了,可是我看了你的理论,根本就画不出图啊:L
回复 使用道具 举报
月光海 发表于 2014-4-17 10:57
s2在创建之后,需要在堆内存中创建一个对象,也就是new一个对象,由于调用了String类的构造函数,往里传了 ...

可以这样理解的吗?

回复 使用道具 举报
⒈心只霸占沵 发表于 2014-4-17 12:21
int a = 1;1会存放在栈里 String s1 = "thanks";thanks会存放在data segment里 String s2 = new String(" ...

常量池在栈里???
我似乎有思路了,哥们能给画张图吗?
回复 使用道具 举报
大概是这样吧,画的有点糟糕。

字符串对象的不同创建方式.jpg (53.56 KB, 下载次数: 14)

字符串对象的不同创建方式.jpg

评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 很给力!

查看全部评分

回复 使用道具 举报
呆呆沙师妹 发表于 2014-4-17 13:22
大概是这样吧,画的有点糟糕。

不是有两个对象吗?你的图中显示只有abc这个对象啊
回复 使用道具 举报
本帖最后由 呆呆沙师妹 于 2014-4-17 14:03 编辑
朱晓盼 发表于 2014-4-17 13:56
不是有两个对象吗?你的图中显示只有abc这个对象啊


"abc"有两个对象,一个在堆内存中,另一个在字符串池中呀
"cde"只有一个,字符串池中的那个
引用变量s1存储的地址是堆内存中"abc"的地址,用s1.intern()能取到字符串池"abc"的地址;
引用变量s2存储的地址是字符串池"cde"的地址。
回复 使用道具 举报
呆呆沙师妹 发表于 2014-4-17 14:01
"abc"有两个对象,一个在堆内存中,另一个在字符串池中呀
"cde"只有一个,字符串池中的那个
引用变量s1存 ...

原来如此,搞明白了,谢谢你了,真是麻烦你了
谢谢楼上所有帮助我的朋友,谢谢
回复 使用道具 举报
其实这句话分两步理解:
String str1="abc";
String str2=new String("");
str2=str1;
所以new String("abc")表示这个字符串指向abc,但是多new了一个空间出来,所以浪费了内存地址
回复 使用道具 举报
  
    



  

无标题.png (26.74 KB, 下载次数: 17)

无标题.png
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马