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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wzg1015 中级黑马   /  2014-10-29 23:56  /  1999 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wzg1015 于 2014-10-30 21:37 编辑

         String str=“”;str+=“a";str+="b",str+="c";是不是每次都会创建一个新的对象?
        另外一个问题,我希望查找这些运算符的底层代码实现来加深理解,可是我不知道应该如何去查找诸如+=这样一类对象使用运算符是如何实现的?是否是实现了特殊接口?

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 赞一个!

查看全部评分

9 个回复

倒序浏览
不是创建新对象,字符串有串池的,指针指向串池。
回复 使用道具 举报
Rain2692 发表于 2014-10-30 00:46
不是创建新对象,字符串有串池的,指针指向串池。

不是=,是+=,追加字符串的。因为一般的建议是使用StringBuilder ,我想问下影响有多大,是不是每次增加长度就算增加一个字符也会新创建对象。
回复 使用道具 举报
同求,相同的疑问点
回复 使用道具 举报
本帖最后由 Eagle 于 2014-10-30 16:26 编辑

这个是The Java Language Specification中3.10.5节的例子
    package testPackage;
    class Test {
            public static void main(String[] args) {
                    String hello = "Hello", lo = "lo";
                    System.out.print((hello == "Hello") + " ");
                    System.out.print((Other.hello == hello) + " ");
                    System.out.print((other.Other.hello == hello) + " ");
                    System.out.print((hello == ("Hel"+"lo")) + " ");
                    System.out.print((hello == ("Hel"+lo)) + " ");
                    System.out.println(hello == ("Hel"+lo).intern());
            }
    }
    class Other { static String hello = "Hello"; }

    package other;
    public class Other { static String hello = "Hello"; }

输出结果为true true true true false true,请自行分析!


结果上面分析,总结如下:
1.单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中.
2.使用new String("")创建的对象会存储到heap中,是运行期新创建的.
3.使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中.
4.使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中.
6.使用"aa" + s1以及new String("aa" + s1)形式创建的对象是否加入到String Pool中我不太确定,可能是必须
调用intern()方法才会加入,希望高手能回答 @_@


还有几个经常考的面试题:

1.
String s1 = new String("s1") ;
String s2 = new String("s1") ;
上面创建了几个String对象?
答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.


原文链接地址:http://bbs.csdn.net/topics/270042906
另外看看这个


  1.      
  2. String s = "abcd";
  3. String s1="a"+"b"+"c"+"d";
  4. System.out.println(s==s1);
复制代码



评分

参与人数 1技术分 +2 收起 理由
杨佳名 + 2 赞一个!

查看全部评分

回复 使用道具 举报 1 0
可以理解为新的对象,由于String只能指向字符串常量,所以推荐使用StringBuilder。字符串连接符“+”是在编译过程中翻译成 new StringBuilder().append().append()......toString() 来实现的。

也就是说诸如+=这样一类对象使用运算符我没查到底层代码,估计是编译器翻译的,你可以看下编译器的代码能不能找到答案。

参考http://blog.csdn.net/sinat_19425927/article/details/38663461

评分

参与人数 1技术分 +2 收起 理由
杨佳名 + 2 赞一个!

查看全部评分

回复 使用道具 举报
编译时期能确定的字符串在栈中,不能确定的在堆中,new的一律在堆中。
回复 使用道具 举报
wzg1015 中级黑马 2014-10-30 20:15:53
8#
jacoblx 发表于 2014-10-30 17:21
可以理解为新的对象,由于String只能指向字符串常量,所以推荐使用StringBuilder。字符串连接符“+”是在编 ...

谢谢,解决了我大部分的问题,看了下,顿时清晰了很多。请问下怎么查看编译后的代码?
回复 使用道具 举报
jacoblx 中级黑马 2014-10-31 02:11:57
9#
本帖最后由 jacoblx 于 2014-10-31 02:13 编辑
wzg1015 发表于 2014-10-30 20:15
谢谢,解决了我大部分的问题,看了下,顿时清晰了很多。请问下怎么查看编译后的代码? ...

额,我也是新手,反编译还不太会,我是找到上述链接中的表述推断的。

看楼下有没会反编译的兄弟
ps:感谢Eagle兄弟的答案,学习了。
回复 使用道具 举报
neokevin 来自手机 初级黑马 2014-10-31 02:25:56
10#
查看源码还是很简单的,首先下载JDK的SRC压缩包,去官网下载,然后用eclipse导入源码,想看哪个类可以在类名上面直接F3就可以了,反编译也可以,插件有很多,可以随便选一个用。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马