String字符串的存储原理(学习笔记)

本文详细探讨了Java中String字符串的存储原理,包括使用双引号和new关键字创建字符串对象的区别。讲解了字符串常量池的概念,并通过实例分析了内存分配情况,强调了String类的不可变性。同时,列举了String类的常用构造方法和方法,强调了equals()方法在判断字符串相等时的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String字符串的存储原理(学习笔记)

关于Java JDK 中内置的一个类:java.lang.String

1.String表示字符串类型,是引用数据类型,不是基本的数据类型。

2.使用双引号括起来的都是String对象。比如:“abc”,“java”,这就是两个String对象。

3.String 类是不可变类,也就是说 String 声明对象以后,将不可修改,“abc"从出生到死亡,不可能变成"abcd”,“ab”。

4.Java中,使用双引号括起来的字符串,都直接存储在"方法区"的“字符串常量池中”

这么做的原因:字符串在实际的开发中使用的太频繁,为了执行效率,所以把字符串放到了方法区的字符串常量池当中。

5.除了双引号的构造方法,还可以通过new的方式来创建字符串对象,如使用:String s3=new String("xy");来创建字符串对象。

​ 两种构造方式有何不同,用以下例子来说明:
 

例1.用双引号创建字符串对象

public class StringTest01{
   
	public static void main(String[] args){
   
        String s1 ="abcdef";
        String s2="abcdef"+"xy";
    }   
}

来画一下这个程序的内存图:

  1. 大框表示JVM虚拟机。里面分为三个部分,方法区,堆和栈

在这里插入图片描述

 
2. 首先会在方法区进行类加载,包括StringTest01.class,String.class,代码片段,静态变量等。

在这里插入图片描述

 
3. 执行main方法,main方法会压栈,生成main方法栈帧。

在这里插入图片描述

 
 
4. 执行main方法的第一句,在方法区的字符串常量池生成String对象"abcdef",其内存地址,比如0x1234。

在这里插入图片描述
 
 
5. 将字符串"abcdef"的内存地址0x1234赋值给了s1,String s1表示一个引用,s1这个局部变量中存放的是"abcd"的内存地址,而不是"abcd"字符串本身。所以在mian方法栈中出现了一个局部变量s1,存储"abcdef"的内存地址0x1234。

在这里插入图片描述
 
 

  1. 执行main方法的第二句,第二句是一个字符串的拼接String s2="abcdef"+"xy";

因为"abcdef"已经在字符串常量池中有了,所以不用再新建,那么会在常量池中创建字符串对象“xy”。

但是注意:此时没有一个引用指向字符串对象"xy"!

在这里插入图片描述
 
 

  1. 由于拼接的操作,在字符串常量池中,字符串对象“abcdef”和字符串对象“xy”进行拼接,生成了新的字符串对象“abcdefxy”,假设它的内存地址是0x2356。

在这里插入图片描述
 
 

  1. 将字符串"abcdefxy"的内存地址0x2356赋值给了s2,String s2表示一个引用,s2这个局部变量中存放的是"abcdefxy"的内存地址,而不是"abcdefxy"字符串本身。所以在mian方法栈中出现了一个局部变量s2,存储"abcdefxy"的内存地址0x2356。

在这里插入图片描述

结论:这两行代码最终创建了3个字符串对象,都存放在字符串常量池中,栈帧中的两个变量存放的是字符串在字符串常量池的内存地址。

 
 

例2:用new方式创建字符串对象

我们在例1的基础上创建s3:

public class StringTest01{
   
	public static void main(String[] args){
   
        String s1 ="abcdef";
        String s2="abcdef"+"xy";
        
        String s3 = new String("xy");
    }   
}

分析:使用new的方式来创建字符串对象,这里的"xy"是从哪里来的?

​ 首先,双引号括起来的都在字符串常量池中有一份

​ 其次当我们new一个对象的时候,是在堆内存中开辟空间

​ 所以在堆内存中创建了一个String对象,里面存放了字符串对象"xy"的内存地址(假设0x5656)。

在这里插入图片描述
 
 
​ 最后在main方法栈帧中,出现了String s3这个变量,保存了String对象的内存地址(假设String对象的堆内存地址是0x1111)。

在这里插入图片描述
结论:如果采用new的方式,在==mian方法栈帧中创建的变量,存储String对象的堆内存地址;==堆内存的String对象则存储字符串在字符串常量池的内存地址</

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值