关于字符串常量池的一些理解

简介:本文尽量不使用代码,用最接地气和通俗易懂的方式来讨论字符串常量池~
主要参考博文:https://blog.csdn.net/u013366617/article/details/83618361

字符串创建的方式

主要有五种方式:
1 字面量(双引号)赋值创建:String s = "abc";
2 new关键字创建:String s = new String("abc");
3 字面量+字面量:String s = "abc" + "qwe";
4 new + new:String s = new String("abc") + new String("qwe");
5 字面量 + new:String s = "abc" + new String("qwe");
我们就从这五种方式,来看看变量在内存中是如何存储的
首先,要明确一个比较重要的概念:字符串存储在字符串常量池中有两种方式:
常量存在引用存在并且这两种方式是不能共存的,也就是说:在一个常量池中,一个字符串如果存在,要么是直接存在,要么是引用存在。
其次,一个String类型的引用,要么是指向常量存在,要么是指向堆的。
那么我们的引用存在,其实就是为了让新的变量,更方便得去指向某个堆中对象,具体的可以看文章最后的关于intern()函数的部分。
在这里插入图片描述

字面量创建

使用字面量创建的时候,会先看字符串常量池中有无该字符串,有——指向常量池中的该字符串(或指向堆中对象);无——创建这个字符串常量并指向它。
在这里插入图片描述

new关键字创建

用new创建时,无论怎样,都会先在堆中创建出该字符串对象并指向。然后再看常量池中有无该字符串:
有——不做任何事情;无——在常量池创建该字符串;(注意这里只是创建,并不会指向)
在这里插入图片描述

字面量+字面量

String s = "abc" + "qwe";

如果程序只执行这行代码,因为编译器的优化,在常量池中,其实只用一个字符串——“abcqwe”
在这里插入图片描述

new + new

String s = new String("abc") + new String("qwe");

只执行这行代码,在堆中会有3个对象:“abc”,“qwe”,“abcqwe”,而在我们的常量池中,只有2个,就是——“abc”,“qwe”。显然,这里我们的s指向的会是堆中的"abcqwe"对象。
在这里插入图片描述

字面量 + new

String s = "abc" + new String("qwe");

这行代码运行后,会在堆中创建两个对象——“qwe”,“abcqwe”。即new的对象和相加后的对象。而在常量池中,会有——“abc"和"qwe”。
在这里插入图片描述
总而言之,用new创建的字符串,既会添加到堆中,也会检查常量池中是否存在,然后做出相应操作。字面量的话,只会去检查常量池中是否存在。而new+字面量和new+new之后的合体字符串,只会放入堆中。

String的intern()方法

该方法返回的是一个字符串,当某个字符串调用了intern(),比如s1.intern();那么,就会去常量池检查有无s1这个字符串,如果没有——则返回堆中s1对象的地址(也就是说,返回的那个字符串变量,将会指向s1的地址)。如果常量池有该字符串,则让intern()返回的那个字符串,指向堆对象或常量对象(取决于该字符串在常量池中是常量存在还是引用存在)。
在这里插入图片描述
执行上图中“②指向常量池”的情况:

  • 常量池中有"abc",并且是常量存在。

执行上图中“②指向堆内存”的情况:

  • 常量池中有"abc",并且是引用存在。
  • 常量池中没有"abc"。(并且会在常量池中创建该字符串的引用存在
最后再补充一个小点,如果是:
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2;

这里的s3,本质上会额外创建一个StringBuffer对象进行拼接,所以还是调用了new,s3自然也是存在堆中的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值