JAVA课程学习第七课:String 类

本文详细介绍了Java中的String类,包括其不可变性带来的好处,如缓存hash值、线程安全等。同时,对比分析了String、StringBuffer和StringBuilder的异同,指出在多线程环境下和性能要求高的场景下的适用选择。此外,还探讨了String Pool的工作原理以及为何不建议在for循环中使用"+"拼接字符串,最后解释了字符串的编码与解码概念。
摘要由CSDN通过智能技术生成


一、String类概览

基础知识

String类被声明为final,因此它不可被继承。(同样的,Integer等包装类也不能被继承)

java8中,String内部使用char数组存储数据。
源代码如下:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
   
    /** The value is used for character storage. */
    private final char value[];
}

java9之后,String类的实现改用byte数组存储字符串,同时使用coder来标识使用了哪种编码。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
   
    
    /** The value is used for character storage. */
    private final byte []value;
    
    /** The identifier of the encoding used to encode the bytes in {@code value}. */
    private final byte coder;
}

其中,value数组被声明为final,这意味着value数组初始化之后就不能再引用其他数组,并且String内部没有改变value数组的方式,因为可以保证String不可变。

String不可变的好处
1. 可以缓存 hash 值

因为Stringhash值经常被使用,例如String用做HashMapkey。不可变的特性可以使得hash值不可变,因此只需要进行一次计算。

2. String Pool 的需要

如果一个String对象已经被创建过了,那么就会从String Pool中取得引用。只有String是不可变的,才可能使用String Pool

3. 安全性

String经常作为参数,String的不可变性保证了参数不可变。例如,在作为网络连接参数的情况下如果String是可变的,那么在网络连接过程中,String被改变,改变String的那一方以为现在连接的是其它的主机,而实际情况却不一定。

4.线程安全

String 不可变性天生具备线程安全,可以在多个线程中安全的使用。

二、请简述String,StringBuffer,StringBuilder三者之间的共同点与区别,应该分别在何种场景下使用?

共同点:

1、内部实现基于字符数组,封装了对字符串处理的各种操作
2、可自动检测数组越界等运行时异常

不同点
1. 可变性

String内部实现基于常量字符数组,内容不可变;
StringBuffer、StringBuilder基于普通字符数组,数组大小可根据
字符串的实际长度自动扩容,内容可变

2.线程安全
  • String 不可变,因此是线程安全的
  • StringBuilder 不是线程安全的
  • StringBuffer 是线程安全,内部使用synchronized进行同步
三者使用场景:

String:对安全要求更高。
StringBuffer、StringBuilder:对性能要求更高。
在实际开发中,95% 的情况使用String,当字符串需要变化时,一般选用StringBuffer。(习惯上的原因,StringBuffer在Java 1.0出现,StringBuilder在Java1.5出发)。

三、String Pool

字符串常量池(String Pool)保存着所有字符串字面量,这些字面量在编译时期就确定。并且也可以通过 Stringintern()方法在运行过程中将字符串添加到String Pool

当一个字符串调用intern() 方法时,

  • 如果String Pool 已经存在着一个字符串和该字符串值相等(用equals()方法进行确定),那么就会返回String Pool中字符串的引用。

  • 否则,就会在String Pool添加一个新的字符串,并且返回这个新的字符串的引用。

测试代码如下:

   String s1=new String("aaa");
   String s2=new String ("aaa");
   //false
   System.out.println(s1==s2);
        
   String s3= s1.intern();
   String s4= s2.intern();
   //true
   System.out.println(s3==s4);

s1和s2采用的是 new String()的方式新建了两个不同的字符串,而s3 和s4则是分别通过s1.intern()s2.intern()方法取得的同一个字符串的引用,intern()首先把aaa放到String Pool中,然后返回这个字符串引用,因此s3和s4 引用的是同一个字符串。

如果采用字面量形式创建字符串,那么会自动将字符串放入String Pool中。

        String s5="bbb";
        String s6="bbb";
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值