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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 依然超级赛亚人 高级黑马   /  2014-7-19 16:38  /  2957 人查看  /  22 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 依然超级赛亚人 于 2014-7-19 16:41 编辑

我们知道,字符串一旦定义就不能再改变,比如以下这几句代码:
String s1="hello";
s1="world";
System.out.println(s1);
打印结果为world.

我们知道,虽然变量s1的结果改变了,但这只不过是它指向了不同的地址(从指向hello变为了指向world)而已,而hello仍然在内存中,没有被改变。不过我想知道到的是我们如果想使用hello这个字符串该怎么操作呢?是在定义一个新变量去引用吗?也就是:String s2="hello";如果是在这样操作,那是又在内存中存了另外一个hello.还是把原来的hello地址赋给了s2?


>>>我估计这个问题对于大家来说可能很简单,但我确实想不起它的原理是上面说的哪一种,或者两种都不对,我也没找到之前的记录,所以还烦请各位给予指导。

22 个回复

正序浏览
依然超级赛亚人 发表于 2014-7-20 22:54
常量池中没有的话就在堆中存储吗?总是感觉有些不对劲。还有,您说常量池也在栈中?恕我有所怀疑,当时老 ...

http://zhidao.baidu.com/link?url=bUnvBfAva7feguKld-m0EUM3TVCaa48HnxOfqzVnG-DOtoTIeF3LGwNib91S_UQwBDlGbi4Vdku_7Wql0-TyQa
也不知道这个算不算、您瞧瞧吧~:)
回复 使用道具 举报
DSY 中级黑马 2014-7-20 23:19:37
22#
依然超级赛亚人 发表于 2014-7-19 22:20
嗯....恕我不敢苟同您的意见,经过前面的一些回答,我也想起了一些东西,也感觉这以上这两种形式的创建方 ...

使用String a =new String("abc")会在栈区或者堆区创建一个新的字符常量,而第二句如果常量池中存在"abc"则不创建,否则就在常量池中创建一个“abc”,就是 使用new 一定会新建个对象
回复 使用道具 举报
as_heima 发表于 2014-7-20 09:30
String str =new String("abc");按我目前学习到的,这个是在堆中开辟个空间,然后去常量池里找有没有"abc ...

常量池中没有的话就在堆中存储吗?总是感觉有些不对劲。还有,您说常量池也在栈中?恕我有所怀疑,当时老师好像没有这样讲过(常量池好像在方法区),您能给一些具有说服性的参考资料吗?
回复 使用道具 举报
導ぷ仙″兲蕐 发表于 2014-7-20 13:05
把原来的hello地址赋给了s2

已经了然,多谢!
回复 使用道具 举报
把原来的hello地址赋给了s2
回复 使用道具 举报
存了另一个HELLO
回复 使用道具 举报
依然超级赛亚人 发表于 2014-7-19 22:14
String str =new String("abc");中创建的这个新串不在常量池?在哪里呢?堆中吗?而且它新生成"abc"不浪 ...

String str =new String("abc");按我目前学习到的,这个是在堆中开辟个空间,然后去常量池里找有没有"abc",如果有,在堆中开辟的空间将存储常量池的地址;如果没有就在堆中存储"abc"~仅供参考:)
回复 使用道具 举报
依然超级赛亚人 发表于 2014-7-19 22:20
嗯....恕我不敢苟同您的意见,经过前面的一些回答,我也想起了一些东西,也感觉这以上这两种形式的创建方 ...

当然同意~不过常量池貌似也在栈中吧:)
回复 使用道具 举报
依然超级赛亚人 发表于 2014-7-19 22:14
String str =new String("abc");中创建的这个新串不在常量池?在哪里呢?堆中吗?而且它新生成"abc"不浪 ...

这个abc在堆中   因为他用了new所以必须开辟空间。堆中有垃圾回收机制  ,
回复 使用道具 举报
icris 中级黑马 2014-7-19 22:46:08
14#
依然超级赛亚人 发表于 2014-7-19 22:10
呃...我有点迟钝,这个程序的目的在于表达....?请明示。

以 s1 的地址做比较基准
s2 是直接引用 s1 的地址(s1 == s2),
s3 是新建另一个 "h"(s1 != s3),
s4 跟 s2 效果相同(至少赋值效果相同)(s1 == s4)
回复 使用道具 举报
as_heima 发表于 2014-7-19 19:27
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";

嗯....恕我不敢苟同您的意见,经过前面的一些回答,我也想起了一些东西,也感觉这以上这两种形式的创建方式都不会在栈或堆中创建对象,它们应该在常量池中创建"abc",不知您是否赞同这个说法?
回复 使用道具 举报
java—family 发表于 2014-7-19 18:59
补充哈,String str = new String("abc");  如果常量池中有adc  是拷贝过去的。常量池中不会存放相同的字符 ...

意思是说没有创造新的"abc"串吗?还是用的原来常量池中已经存在的旧串?
回复 使用道具 举报
java—family 发表于 2014-7-19 18:48
1.java运行环境有一个字符串池,由String类维护,执行语句String str="abc"时:                           ...

String str =new String("abc");中创建的这个新串不在常量池?在哪里呢?堆中吗?而且它新生成"abc"不浪费内存空间吗?
回复 使用道具 举报

呃...我有点迟钝,这个程序的目的在于表达....?请明示。
回复 使用道具 举报
fantacyleo 发表于 2014-7-19 18:10
String s1="hello";这句之后,"hello"会被存到常量池中。String s2="hello";会让s2指向常量池中的"hello", ...

OK,终于知道了它的原理。:handshake
回复 使用道具 举报
icris 发表于 2014-7-19 18:05
String s2 = "hello"; 是把原来的hello地址赋给了s2
String s2 = new String("hello"); 是又在内存中存了另 ...

恩啊,知道了,hello放在常量池,s2指向它的时候,它就把自己的地址赋给它了。
回复 使用道具 举报
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对 String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
回复 使用道具 举报
补充哈,String str = new String("abc");  如果常量池中有adc  是拷贝过去的。常量池中不会存放相同的字符串
回复 使用道具 举报
1.java运行环境有一个字符串池,由String类维护,执行语句String str="abc"时:                                                                                                                                         1.首先查看字符串池中是否存在字符串"abc",如果存在则直接将“abc”赋给str,如果不存在则先在  字 符串池中新建一个字符串"abc",然后再将其赋给str.  2.执行语句String str = new String("abc");时。不管字符串池中是否存在字符串“abc”,直接新建一个字符串“abc”,(注意,新建的字符串“abc”不是在字符串池中),然后将其赋给str  。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马