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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 ↘ふ紫铯幽夢 于 2014-5-29 09:38 编辑

关于String s="a"+"b"+"c"究竟在内存创建了几个对象这个问题,以前也有人发过,但是看到好多人回复都说创建了多个对象,也有人说只创建了一个。  到底那个答案是对的。该怎么去证实,有没有更权威的回答。小弟万分感谢。

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

14 个回复

倒序浏览
首先要明确的是以String s = "abc"这种形式创建的字符串是存储在常量池中的,如果常量池中有相应的字符串则不创建新的字符串对象,即不重新在常量池中分配空间。
lz的例子中,如果之前以上述形式创建过"abc"这个字符串,则String s="a"+"b"+"c"这个语句实际上是没有创建对象的,而是直接返回常量池中"abc"的引用,否则,就在常量池中创建一个"abc"的字符串对象,因此是创建了0个或1个对象!!!!

点评

完全正确,编译器对字符串【常量】操作有做功能上的优化,"a"+"b"+"c"这种会被直接优化成"abc"来进行操作。  发表于 2014-5-28 10:48
回复 使用道具 举报 5 0
首先,其实+连接符是通过StringBuffer类和它的append方法实现的,
String s = "a"+"b"+"c";这句代码在编译时就等效于
String s = new StringBuffer().append("a").append("b").append("c").toString();
所以个人认为,内存中应该是创建了一个StringBuffer的对象。

评分

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

查看全部评分

回复 使用道具 举报
这个问题的标准答案  面试肯定不会让你去考虑缓存已经有的情况        假如 a b c已经在常量池中存在的话   就是只创建了一个string对象
回复 使用道具 举报
String是引用类型  
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abc”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,
           String s = "a" + "b" + "c";
           System.out.println(s == "abc");
最终打印的结果应该为true。
所以  上面的代码在内存中只创建了一个String对象

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报 1 0
Lin0411 发表于 2014-5-27 19:51
首先要明确的是以String s = "abc"这种形式创建的字符串是存储在常量池中的,如果常量池中有相应的字符串则 ...


这个答案貌似合理,有没有什么工具和方法可以查看堆内存中的对象来证实。。。
回复 使用道具 举报
想飞的鱼 发表于 2014-5-27 20:48
首先,其实+连接符是通过StringBuffer类和它的append方法实现的,
String s = "a"+"b"+"c";这句代码在编译 ...

怎么证实。。。
回复 使用道具 举报
想飞的鱼 发表于 2014-5-27 20:48
首先,其实+连接符是通过StringBuffer类和它的append方法实现的,
String s = "a"+"b"+"c";这句代码在编译 ...

以StringBuffer类创建的字符串是存储在堆内存中的,而String s="a"+"b"+"c"这种形式创建的字符串是放在常量池中的,如果是这样的话,有点矛盾咧。。。。。。。
回复 使用道具 举报
ithmC4 中级黑马 2014-5-28 11:19:31
9#
知识点:编译器对字符串常量表达式进行优化
1.
String s1 = "abc";
String s2 = "a" + "b" + "c";
String s3 = "a" + "b" + "c" + ""; //这种我没试,应该也和前面两个一样的,你可以试试
String s4 = "a" + "b" + 'c';
前三种是一样的,因为编译器会对之后二种进行字符串常量表达式进行优化,变成第一种来操作:先查常量池,有就引用,没有就在常量池种创建再引用
第四种'c'是char类型,不是字符串常量,不能优化,这时用的是StringBuilder来append

2.
String s1 = "a";
String s2 = s1 + "b" + "c";
这种情况因为S1也是个字符串常量所以也会被优化成"abc"来处理

3.
String s1 = new String("a");
String s2 = s1 + "b" +"c";
这里S1是一个变量,因为它可以不是常量而是任何字符串,可能不在常量池中,所以不进行优化而是是用StringBuilder来append

如果还不懂百度关键词:Java常量表达式优化
回复 使用道具 举报
ithmC4 发表于 2014-5-28 11:19
知识点:编译器对字符串常量表达式进行优化
1.
String s1 = "abc";

有道理。。。。
回复 使用道具 举报
ithmC4 发表于 2014-5-28 11:19
知识点:编译器对字符串常量表达式进行优化
1.
String s1 = "abc";

受教育了
回复 使用道具 举报
综上所述,创建1个对象
回复 使用道具 举报
这个应该创建了多个对象,你可以根据String这个类去分析它,String这个类是不可以改变的类,比较特殊!
回复 使用道具 举报
长姿势了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马