Java中关于字符串常量池的详解!!!

前言

Java使用 “ ” 称为字符串常量,为了提高程序的运行速度,节省空间,JVM会维护一个字符串常量池。当字符串常量第一次出现,则产生新对象并将该对象置入常量池中,后续如果再出现该字符串常量,不会产生新对象,直接复用常量池中的已有对象。

1. 直接赋值法,默认从常量池中取对象

  • “ ” 内容都是字符串常量,都是字符串对象
  • 字符串对象不可变,无法修改value的内容
//第一次出现,产生新对象,入池
String s1="hello";
//第二次出现,不会产生新对象
String s2="hello";

以上代码的内存示意图s1==s2
在这里插入图片描述

2. new一个对象

  • new一个对象,需要调用构造方法进行新对象的创建。
  • 每调用一次new,都会在堆上开辟新空间,返回新创建的对象。
  • 总之:看见new就会产生新空间!!!
    对如下代码进行分析:
//直接赋值法
String s1="hello";
String s2="hello";
//构造方法产生新对象
String s3=new String("hello");
String s4=new String("hello");

分析:对于s1和s2来说,属于直接赋值类型,产生字符串对象放入字符串常量池,s2将会直接从字符串常量池取出已有对象,则s1==s2。s3属于构造方法new一个新对象,需要在堆区开辟一个新的空间,其中value值保存的是字符数组的地址。
在这里插入图片描述
上述代码共产生三个对象,一个在常量池中,两个在堆上;产生了4个引用,其中s1和s2指向的是常量池中的对象,s3和s4分别指向的是堆中的对象。

3. 字符串常量池、字符串对象、内部的value引用、具体的字符数组之间的关系

  • 字符串常量池中保存的都是字符串对象;
  • 字符串对象内部的value引用是指向字符数组的引用;
    举例:
    假如将CSDN的博客内容相当于字符数组的内容;value引用保存了这块内容的地址;字符串对象相当于博客链接;CSDN相当于字符串常量池,保存了许多字符串对象,即链接!
    new出来的字符串对象中的value引用,只是一个名字,指向字符数组,不是实体!!!

4. 手动入池方法:intern方法

将手动创建的字符串对象置入常量池,并返回置入常量池之后的地址。
看如下的代码:

char[] ch={'a','b','c'};
String s1=new String(ch)String s2="abc";
System.out.println(s1==s2);

s1:通过new的方式产生的字符串仍然在堆中存储,不会置入常量池
s2:字符串常量产生后直接置入常量池
s1 != s2

char[] ch={'a','b','c'};
String s1=new String(ch);
s1.intern();
String s2="abc";
System.out.println(s1==s2);

此时,将堆上new出来的新对象通过intern()方式手动置入常量池,当“abc”出现时,常量池中已经包含,因此,s2直接返回常量池中存储的地址。
s1 == s2
在这里插入图片描述

String s2="abc";
char[] ch={'a','b','c'};
String s1=new String(ch);
s1.intern();
System.out.println(s1==s2);

此时,s2属于直接赋值法将产生的字符串对象直接放入字符串常量池中;
s1属于new出来的对象放置在堆区,s1.intern()方法执行后的返回值无人接收,s1依旧指向的是堆区的字符串对象的地址。
s1 != s2
在这里插入图片描述

补充介绍intern()方法
尝试将当前字符串对象置入常量池;
若常量池中不存在该对象内部保存的内容“abc”,则将当前对象置入常量池;
若常量池中已经存在该对象保存的内容,则该方法直接返回常量池中的字符串对象地址!
intern()方法调用后会返回常量池中的字符串地址,调用之后进行接收即可!

如果让s1去接收intern()方法的返回值,此时由于字符串常量池中包含字符串“abc“,因此直接返回常量池中的字符串对象地址,则s1==s2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值