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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 黑马-王鹏 于 2013-3-15 23:57 编辑

String s = "Hello";s = s + " world!";两行代码执行后,原始的String对象中的内容到底变了没有?为什么?
与附件无关,附件传错,不好意思哈

KI6QEH5N{0N1 (67.56 KB, 下载次数: 61)

KI6QEH5N{0N1

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

8 个回复

倒序浏览
刚才附件传错了,与附件代码无关,
回复 使用道具 举报
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向了。
我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报

回帖奖励 +5

这个我来说说,
String s = "Hello";
s = s + " world!";
s只是变量的引用,存的是地址,String类一旦初始化就不可改变的意思是,String s = "Hello";“hello在方法区不会变”。但是s是引用,可以变,所以当s + " world!";之后会在堆内存中产生一个新的字符串,然后把其内存地址赋给s。
而原来的“hello”,随后会被垃圾回收机制处理掉

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

回复 使用道具 举报
S的值已经改变成为helloworld

程序在运行的时候会创建一个字符串缓冲池,程序会把字符串常量放入字符串缓冲池中String s = "Hello"

但是在这些赋值中,涉及到变量运算,所以得到的字符串对象存储在各自的内存中,不是缓冲池中的S对象s = s + " world!"
回复 使用道具 举报
String s = "Hello";s = s + " world!"原有的对象中内容没有改变.String类为不可变类."Hello"和"world"都是存储在方法区中的常量池中,对s进行+操作,s指向的那个对象是不会发生改变的,s所指向的内容变成了"Helloworld".
回复 使用道具 举报
jdzzlf 中级黑马 2013-3-15 23:43:52
7#
String对象的内容改变了。
String有一个非常重要的特性,那就是字符串内容一旦声明就不可改变。
原理机制为:
String在堆内存中有Hello,World,Hello World三个内存空间。
所以String对象的内容的改变实际是通过内存地址的断开-连接而完成的,本身的字符串内容没有任何变化。
回复 使用道具 举报
String对象不像StringBuffer和StringBuilder,String对象一经创建就无法改变了,你在其后面新添加一个字符串,意思是由创建了一个String对象,原来的s指向了新创建的这个对象,原来的对象失去引用就成为了垃圾对象等待垃圾收集器来清理,Buffer和StringBuilder则不会这样
回复 使用道具 举报
赞同二楼的!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马