黑马程序员技术交流社区

标题: String 的问题以及+=的底层实现问题 [打印本页]

作者: wzg1015    时间: 2014-10-29 23:56
标题: String 的问题以及+=的底层实现问题
本帖最后由 wzg1015 于 2014-10-30 21:37 编辑

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

作者: Rain2692    时间: 2014-10-30 00:46
不是创建新对象,字符串有串池的,指针指向串池。
作者: wzg1015    时间: 2014-10-30 01:28
Rain2692 发表于 2014-10-30 00:46
不是创建新对象,字符串有串池的,指针指向串池。

不是=,是+=,追加字符串的。因为一般的建议是使用StringBuilder ,我想问下影响有多大,是不是每次增加长度就算增加一个字符也会新创建对象。
作者: 践行渐远    时间: 2014-10-30 11:32
同求,相同的疑问点
作者: Eagle    时间: 2014-10-30 16:23
本帖最后由 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);
复制代码




作者: jacoblx    时间: 2014-10-30 17:21
可以理解为新的对象,由于String只能指向字符串常量,所以推荐使用StringBuilder。字符串连接符“+”是在编译过程中翻译成 new StringBuilder().append().append()......toString() 来实现的。

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

参考http://blog.csdn.net/sinat_19425927/article/details/38663461
作者: OnlyStyle    时间: 2014-10-30 19:32
编译时期能确定的字符串在栈中,不能确定的在堆中,new的一律在堆中。
作者: wzg1015    时间: 2014-10-30 20:15
jacoblx 发表于 2014-10-30 17:21
可以理解为新的对象,由于String只能指向字符串常量,所以推荐使用StringBuilder。字符串连接符“+”是在编 ...

谢谢,解决了我大部分的问题,看了下,顿时清晰了很多。请问下怎么查看编译后的代码?
作者: jacoblx    时间: 2014-10-31 02:11
本帖最后由 jacoblx 于 2014-10-31 02:13 编辑
wzg1015 发表于 2014-10-30 20:15
谢谢,解决了我大部分的问题,看了下,顿时清晰了很多。请问下怎么查看编译后的代码? ...

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

看楼下有没会反编译的兄弟
ps:感谢Eagle兄弟的答案,学习了。

作者: neokevin    时间: 2014-10-31 02:25
查看源码还是很简单的,首先下载JDK的SRC压缩包,去官网下载,然后用eclipse导入源码,想看哪个类可以在类名上面直接F3就可以了,反编译也可以,插件有很多,可以随便选一个用。




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