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中文社群 - 博客园  

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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 ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值