---恢复内容开始---
起因是在刷题时偶遇的一道关于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
时间: 2024-10-31 01:53:22