当前位置: 首页 > >

String字符串的存储原理

发布时间:


1.String表示字符串类型,属于引用数据类型,不属于基本数据类型
2.在java中用双引号括起来的都是String对象:例如:"abc","def","hello world","你好"
3.java中规定,双引号括起来的字符串,是不可变的,也就是说"abc"到最终死亡,不可变,不能变成"abcd",也不能变成"ab"
4.在JDk当中双引号括起来的字符串,例如"abcd"都直接存储在方法区的"字符串常量池"当中的。
5.凡是双引号括起来的都在字符串常量池中有一份。
6.为什么SUN公司把字符串存储在一个"字符串常量池"当中呢。因为字符串在实际开发中使用太频繁,为了执行效率,把字符串放到方法区的"字符串常量池"当中。



一、创建字符串对象的两种方式
①方式一:String s1 = "hhh";

1.在编译期,JVM会去字符串常量池查找是否存在"hhh"
2.如果不存在,就在常量池开辟一个空间来存储"hhh",把地址赋给栈指针
3.如果存在,就不用开辟新的空间,直接把地址赋给栈指针
4.然后在栈内存中开辟一个名为s1的空间,来存储"hhh"在常量池中的地址


总结:可能创建一个对象(在字符串常量池中),也可能不创建对象(在字符创常量池中已存在该对象)


②方式二:String s2 = new String("hhh");

1.在编译期,JVM会去字符串常量池查找是否存在"hhh"
2.如果不存在,就在常量池开辟一个空间来存储"hhh"
3.如果存在,就不用开辟新的空间
4.在运行期,通过String的构造器在堆内存中new了一个新的空间(new?Sring("hhh"))
5.然后将常量池中的"hhh"对象的地址复制一份到该堆内存的空间中
6.在栈内存中开辟一个名为s1的空间,存放堆内存中新空间的地址


总结:不管字符串常量池中是否存在将要创建的字符串对象,以new的方式创建字符串对象,就一定会在对堆内存中创建一个对象(用来存放字符串对象在方法区的字符串常量池中的地址)。至少创建一个对象


内存图:


二、字符串拼接的原理
原理:

1. 先在字符串常量池中,查找是否存在要拼接的字符串对象:"abcd"和"ef"


2. 如果不存在,就在常量池开辟一个空间来存储字符串对象:"abcd"和"ef"


3. 如果存在,先把两个字符串对象拿来拼接成新的字符串对象,并在字符串常量池中开辟一个空间,用来存放新的字符串对象


4.?然后在栈内存中开辟一个名为s3的空间,来存储"abcdef"在常量池中的地址


代码:

public class StringTest01 {
public static void main(String[] args) {
//这三行代码表示创建了4个字符串对象,3个在字符创常量池中,一个在堆内存中
String s1 = "abcd";
String s2 = new String("ef");
String s3 = "abcd"+"ef";
}
}

内存图:?


三、字符串对象作为实例变量?


这边有篇博文写的挺好的,挺清楚的,推荐看一下,我也是整理完才发现的宝藏:


别再问我 new 字符串创建了几个对象了!我来证明给你看! - Java中文社群 - 博客园 ?



友情链接: