网上对于String对象的创建说的五花八门,各有各的说法,越看越懵逼,所以结合相关资料,说一下我的理解,不知道是不是正确。
首先要声明的是:
1.String是final类,说明它声明的变量的地址都是不可以修改的,注意是地址已经固定了,改的只是引用指向的值。
2.String的引用,也可理解为指针,是不算创建对象的。不知道怎么解释,引用是放在java栈里的,为什么就不算创建呢。
然后我们再来看String创建对象
1. String a=“1”;//毫无疑问,这句话创建了一个对象,这个对象是 【常量对象】:“1”,而引用a指向了常量对象。
2. String b=new String("2");//毫无疑问,这句话创建了两个对象,一个是在new String出来的对象“2”,存在堆上;一个是【常量对象】:“2”,b是引用,指向堆上的对象。
下面重点来了:
接着上面的代码,继续写如下语句
3. String c=“1”;//这个时候,因为上面的第一条语句已经创建了常量对象1,它已经存在常量池里了,所以没有创建对象,引用c指向了常量对象;
4. String d = new String("1");//new String肯定是要创建一个对象在堆上的;而常量对象“1”已经在常量池里了,所以这条语句只创建了一个对象;引用d指向了堆上的对象。
5. String e = "1"+"2"+"3";//创建了一个常量对象“123”,因为java虚拟机在编译常量表达式时会进行优化,如下图所示,
--->
6. String f = "1"+a;//常量对象1上面已经创建过了,a对象也是在上面创建过了,所以这条语句也只创建了一个常量对象11
7. String g = "3"+a;//常量对象3在常量池中找不到,所以会在常量池中创建常量对象3,以及常量对象31;
以上,是所有String创建对象的思考~然后继续按照这个思路思考下面的问题:
a = “31”;//常量对象31已经存在,所以只是a的引用改变了,
然而,我在看string,stringbuilder和stringbuffer区别时,看到以下这段话
大致意思是,str=str+“de”会把之前的str删掉,而创建新的str并赋值,这和我上面的解析是完全背离的,所以基于上述我的思考逻辑,我重新分析string的速度为什么会比其他两个要慢的原因是,str=“abc”;str=str+"de";这两句话一共要创建3个常量对象,分别是abc,de,abcde,而str需要从一开始指向abc的引用,转而去指向abcde,创建常量的和换引用比较费时间。所以比另外两个字符处理类要慢。
参考文章:https://blog.csdn.net/njiang/article/details/43971941
https://www.cnblogs.com/su-feng/p/6659064.html