字符串常量池

6. String Table

6.1 String的基本特性

  • String声明为final,不可被继承
  • 实现了Serializable接口:支持字符串序列化
  • 实现了Comparable接口:可以比较大小
  • jdk8之前定义final char[] value储存字符串数据,jdk9之后用byte[]

String的不可变性。

字符串常量池是不会存储相同内容的字符串。

-XX:StringTableSize设置StringTable的长度。(JDK8最小值为1009)

String的String Pool是固定大小的HashTable

6.2 String的内存分配

  • 双引号声明出来的String对象会直接储存在常量池
  • 使用String提供的intern()方法。

字符串常量池在堆中。

6.3 字符串拼接操作的面试题讲解

字符串拼接操作

  • 常量与常量的拼接在常量池中,原理是编译期优化
  • 常量池中不会存在相同内容的常量
  • 只有其中有一个是变量,结果就在堆中(new String(),具体的内容就是拼接的结果)。变量拼接的原理是StringBuilder
  • 如果拼接的结果调用intern()方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址。

intern():判断字符串常量池中是否存在该字符串的值,如果存在则返回常量池的地址,如果不存在,则放入常量池并返回地址。

== 和 equals()

  • ==:直接比较两个对象的堆内存地址
  • equals():对于Object而言是一样的,但是这个方法可以重写,所以可以写成与内容一致。

拼接的底层细节

/*
String s1="a";
String s2="b";
String s3=s1+s2;
String s4="ab";
*/
/*
s1+s2的细节:
StringBuilder s=new StringBuilder();
s.append("a");
s.append("b");
s3=s.toString();  //toString()类似于new String("ab");
sout(s3 == s4);//true
*/

拼接操作和append的效率

拼接操作的效率会比append远远的低。

StringBuilder的append()方式的好处:自始至终只创建过一个StringBuilder的对象

String的字符串拼接方式:创建多个StringBuilder和String对象。内存占用更大,如果进行GC,需要花费格外时间。

在实际开发中,如果基本确定前前后后添加的字符串长度不高于某个限定值highlevel的情况下,建议使用StringBuilder s=new StringBuilder(highlevel)

intern()方法的使用

String{
    public native String intern();
}
String myInfo=new String("I love NUAA").intern();
//intern()方法会从字符串常量池中查询当前字符串是否存在,如果不存在则将当前字符串放入常量池中,返回的是该字符串常量池中的地址

保证String变量s指向的是字符串常量池中的数据?

String s="wangguofu";
String s=new String("wangguofu").intern();
String s=new StringBuilder("wangguofu").toString().intern();

intern()更加深入理解

public class StringIntern1{
    //在jdk6是一种结果 在jdk7/8的时候是另外一种结果(由于字符串常量池存储的内存位置发生了变化)
    main(){
        String s=new String("1");
        s.intern();
        String s2="1";
        sout(s==s2);//jdk6: false jdk7/8:false
        
        String s3=new String("1")+new String("1");
        s3.intern();
        String s4="11";
        sout(s3==s4);//jdk6:false  jdk7/8:true
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5qZiEmWb-1615212272653)(https://i.loli.net/2021/03/08/87UBrGgh4MpYqvd.png)]

new String(“ab”)会创建几个对象?

会创建两个对象。(可以看字节码)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f10k1IPl-1615212272655)(https://i.loli.net/2021/03/08/7iR9fuJqHEGYv1t.png)]

一个是String的对象,一个是字符串常量池"ab"的对象

new String(“a”)+new String(“b”)会创建几个对象?

image-20210308213837152

对象1:new StringBuilder()

对象2:new String(“a”)

对象3:字符串常量池中 “a”

对象4:new String(“b”)

对象5:字符串常量池中的"b"

深入剖析:

对象6:StringBuilder.toString()

强调一下toString()方法的调用,在字符串常量池中没有"ab"(这个toString方法的new String()传参的是char[])

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值