String字符串的存储原理

1.String存储类型:引用数据类型

        String类型与数组类似,属于引用数据类型。在Java中,是通过创建对象存储其地址的形式来指向具体的字符串。在JDK8之前,字符串本身是存储在JVM的方法区的字符串常量池中。(JDK8以后存储在堆内存中)

2.String创建方式

        (1)静态创建

String a1="this is a String!"

                创建方式如上图。在创建String类型的变量的时候建议使用直接赋值的方法去创建对象,在多个变量使用同一个字符串的时候,会指向通一块字符串(即存储地址相同)字符串会放在常量池当中(常量池是堆内存中的一块特殊区域–常量池的位置变化在文末),不管创建多少个对象,都是引用的常量池的那个字符串。

          (2)动态创建

String a2=new String("this is a string");

                  创建方式如上图,运用String类的构造方法进行创建。主义,采用new 的方法的话,创建出来的变量是放在栈内存中,每个实际对象都会在堆中开辟出新的内存空间来完成储存,不管字符串是否一致。

            (3)图解两种创建方式的异同

              

String s1="abcdef";
String s2="abcdef"+"xy";//字符串间可用“+”拼接
String s3=new String("abcdefxy");

                  由图可知,我们通过静态创建方法来创建s1和s2变量,用动态创建方法new出一个s3对象来指向字符串常量池。不难发现,对于s1和s2,其引用是直接指向方法区中的字符串常量池的。

而s3则不同,通过new的对象,在堆中有了一个实例后,再通过该实例指向字符串常量池中相应的字符串,相较于静态创建,相当于是多了一个“中间商”进行指向。

                 为了更加具体的区分其异同,这里我们都以“aa”字符串作为代表。通过上图可知,通过String构造方法new出的对象s、s1、s2是独立开的三个对象(想想是为什么呢?)答案很简单,我们在栈内存中声明的类型是指向堆中创建出的三个不同地址的对象,而这三个不同的对象各自在不同的地址,即使这三个对象指向的又是同一个地址,它们也已经是不同的了。这里可能有点绕,缓缓可以想明白。

                 然后我们再来看直接赋值方法创建,不难发现,s、s1和s2指向了常量池中的“aa”,所以可以这样认为,它们指向了同样的地址,即s1==s2==s3(除了变量名,其余全都相同)。

                 通过上述,留给读者一个思考题作为自测:

               

String s1="abc";
String s2="abc";
String s3=new String("abc");

//问:该过程一共创建了多少对象,试着用上述图解的方法答出来。

 

                  

String在JVM中的存储方式是通过一个char数组来存储字符串的字符数据。在JDK8及以前的版本中,String内部定义了一个final char\[\] value来存储字符串数据。而在JDK9中,String存储结构发生了变化,改为了使用byte\[\]来存储字符串数据。\[2\] String对象在JVM中的存储位置有两种情况: 1. 字符串常量池:在JDK中,双引号括起来的字符串常量,例如"abc"、"def",都是直接存储在方法区的字符串常量池中。这是因为字符串在实际开发中使用非常频繁,为了提高执行效率,将字符串放在字符串常量池中。 2. 堆内存:使用new关键字创建的字符串对象会在堆内存中开辟空间。例如在示例代码中,使用new关键字创建的字符串对象"c",会在堆内存中开辟空间存储字符串数据。\[3\] 需要注意的是,字符串是不可变的,即一旦创建就不能修改。这是因为String类被声明为final,不可被继承,并且String对象在JVM中是不可变的。这意味着一旦字符串对象被创建,它的就不能被改变。\[3\] #### 引用[.reference_title] - *1* [【JavaString字符串在JVM中的存储及其内存地址问题](https://blog.csdn.net/weixin_43390123/article/details/124376835)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [JVM上篇_13_StringTable_尚硅谷](https://blog.csdn.net/weixin_43811294/article/details/125462300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Java基础String字符串存储原理](https://blog.csdn.net/qq_46096136/article/details/126533585)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛变涡流

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值