首页 > 代码库 > 关于String的一点小笔记

关于String的一点小笔记

---恢复内容开始---

起因是在刷题时偶遇的一道关于String 对象引用的问题

**
 * Created by XIAO on 2017/4/2 0002.
 */
public class stringTest {
    public static void main(String[] args){
        String s1 = "Hello";
        String s2 = s1 + " world";
        System.out.println(s2 == "Hello world");   //false
        String s3 = "Hello" + " world";
        System.out.println(s3 == "Hello world");   //true
    }
}

开始时,我以为只是简单的对象引用不同,但是,再粗略的画了一下堆栈的关系后,我发现我错了,这里的主要问题还是String函数在编译期对内存的分配管理。

String s3 = "Hello" + " world";

这段代码,在编译期会常量重叠,javac会帮助我把值算出来,然后赋值给s3,所以这句话在实质上是等于直接创建 s3而不使用连接符的。也就是以下的代码:

String s3 = "Hello World" ;

然后由于栈中的字符串池的存在,使得技术分享中的两个实质上是同一个对象的不同引用。

这个之所以在前面说,是因为我觉得它比较简单,而且这个是首先就应该能想到的。

 

接下来要说的是我当时并不是特别清楚的一部分

也就是在Java中字符串 "+"的内部实现。

竖起来很惭愧,之前我以为是使用String函数的contact方法实现的,但是在知乎上看到了一个比较好的回答才发现,它在实质上是调用了StringBuilder的append方法实现的。

也就是说:

String s2 = s1 + " world";
//这段代码和下面的代码实质上相同
String s2 = new StringBuilder().append(s1).append("world");

它new了一个对象,new出来的东西位于堆上,也就是说s2指向了堆上的一块内存,而s3指向的位于常量池,所以使用==会返回false

 

关于String的一点小笔记