字符串常量池、堆、栈

时间:2021-11-18 10:12:46


String a="a"+"b"+"c" 创建了几个对象


这个问题涉及到了字符串常量池字符串拼接


String a="a"+"b"+"c"


通过编译器优化后,得到的效果是

String a="abc"


Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";

另一种就是使用new这种标准的构造对象的方法,如String str = new String("droid");

这两种方式我们在代码编写时都经常使用,尤其是字面量的方式。然而这两种实现其实存在着一些性能和内存占用的差别。这一切都是源于JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池


当我们使用了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象,新的字符串对象都会创建(在堆中)。



:存放所有new出来的对象;

存放基本类型的变量数据和对象的应用,对象(new出来的对象)本身并不存在栈中,而是存放在堆中或者常量池中(字符串常量对象存放在常量池中);

常量池:存放基本类型常量和字符串常量。


 对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。

       而对于字符串来说,其对象的引用都是存储在栈中的,如果是编译期已经创建好(即指用双引号定义的)的就存储在常量池中,如果是运行期(new出来的对象)则存储在堆中。对于equals相等的字符串,在常量池中是只有一份的,在堆中则有多份。



两个深入阅读的链接
 字符串常量池: droidyue.com/blog/2014/
 字符串拼接内部实现:droidyue.com/blog/2014/


本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1733249