黑马程序员技术交流社区

标题: 旧题重谈,String s = new String("abc");的一点看法。 [打印本页]

作者: 李建强    时间: 2012-10-2 22:53
标题: 旧题重谈,String s = new String("abc");的一点看法。
String s = new String("abc");
很多人都知道是创建了两个对象。
一个是常量池中的常量,一个是堆中new出的对象。

那么,如果常量池中已经存在了一个常量"abc"呢?
众所周知,常量池是在编译器已经确定好的,
其中包括:类、方法、接口中的常量,也包括特殊的字符串常量。

String s = "abc";
这句代码过程大致:
String s创建一个引用,JVM去pool寻找"abc",找到后指向,
找不到创建对象、放进常量池再返回指向,判断依据是equals。

String s = new String("abc");
这句代码过程大致:
String s创建一个引用,JVM去pool寻找"abc",找不到就创建,
注意这里找到找不到都不指向。接着在堆中创建了一个字符串对象,引用指向了堆中对象。

OK,我写了这么多,我想说的是如果常量池中存在了字符串常量,
那么String s = new String("abc");就只会在堆中创建一个对象了吧?
这种情况适用于:
String s = "abc";
String s = new String("abc");
这时候第二句就只创建了一个对象?不知道这样说理解是否有误,请高手指教。


还有,下面这一句,是创建了几个对象?
String str=new String()+"abc"一共创建了几个对象?



作者: 尤洋    时间: 2012-10-2 23:10
String s = "abc";
String s = new String("abc");
第二句只创建了一个对象

String str=new String()+"abc"一共创建了2个对象
因为new String()是引用数据类型 必须在堆内存中对象实例化过程中 进行 默认初始化时才能确定其值
所以无法再编译阶段 去掉加号直接连接
因此 会先 生成 默认值为null 的String 对象 和 “abc”两个对象
两者相加后仍然为“abc”所以不产生新对象,而是把引用变量 str指向“abc”。
最终就只产生了两个对象
作者: 曾浩    时间: 2012-10-2 23:28
http://bbs.itheima.com/blog-17732-670.html   这里面说的很清楚 可以自己看看
作者: 夏天    时间: 2012-10-4 12:06
啦啦啦,马上升级金牌黑马~~ 是帖我就顶~~
作者: 李建强    时间: 2012-10-4 12:34
夏诗瑶 发表于 2012-10-4 12:06
啦啦啦,马上升级金牌黑马~~ 是帖我就顶~~

小心给你扣成负数~~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2