Java基础(六):String类源码解析

本文详细介绍了Java中String类的不可变性,从类声明、属性字段、构造方法和常用方法等方面进行源码分析。讨论了String类不可变的原因,包括字符串常量池、HashCode缓存、安全性及线程安全等因素,并探讨了如何实现一个不可变类。同时,通过反射实验展示了虽然String对象本身不可变,但其内部引用的数组元素在特定情况下可被修改。
摘要由CSDN通过智能技术生成

一.String类引入了哪些包?

import java.io.ObjectStreamField;//流处理支持
import java.io.UnsupportedEncodingException;//流处理支持
import java.nio.charset.Charset;//编解码支持
import java.util.ArrayList;//数据结构支持
import java.util.Arrays;//数据结构支持
import java.util.Cimparator;//相关的一些特性
import java.util.Formatter;//相关的一些特性
import java.util.Locale;//相关的一些特性
import java.util.Objects;//相关的一些特性
import java.util.StringJoiner;//相关的一些特性
import java.util.regex.Matcher;//正则支持
import java.util.regex.Patten;//正则支持
import java.util.regex.PatternSyntaxException;//正则支持

二.String的类声明

public final class String
    implements java.io.Serializable,Comparable<String>,CharSequence
  • final修饰符决定了String类是不可继承的且对象是不可变的,无法写一个继承自String的类,String对象的不可变性下面会再提
  • 实现Serializable接口,用来保证String可以序列化和反序列化,此序列化接口没有任何方法和域,仅用于标识序列化的语意
  • Comparable的compareTo(String str)方法则是实现String的对比排序的
  • CharSequence的length()方法用来返回字符串长度,charAt(int index)则可以获取到给定位置的单个字符,subSequence(int start,int end)则提供了截取子字符串的功能,toString()方法对于String来说就是返回它自己了。

三.String的属性字段

//一个不可变的char数据用来存放字符串
//并且是final类型的,不可变
private final char value[];

//用来存放string的哈希值
private int hash;

//提供序列化的ID
private static final long serialVersionUID = - 6849794470754667710L;

//声明了一个可序列化的字段
private static final ObjectStreamField[] serialPersistentFields = 
    new ObjectStreamField[0];

很多人都会对serialPersistentFields有疑问,看定义,它是一个私有的、静态的、不可改变的ObjectStreamField数组,世界上在JDK源码里有很多类都有这样一个属性,这些类的共同点是都实现了java.io.Serialzable接口。在默认情况下一个实现了Serialzable接口的类,所有的非transient非static修饰的字段都会被序列化,但如果还定义了serialPersistentFields字段,则只有serialPersistentField里添加的字段才会被序列化。当一个字段用transient修饰,但又位于serialPersistentField数组里,它依然会被序列化。--说明serialPersistentField的作用优先级是比Transient高的。

从上面可以看出String类其实是通过char数组来保护字符串的,String类是Java中最频繁使用的类之一,所以开发者们也在不断的对String类进行优化,String类的演进如下:

四.String的构造方法

/** 01
* 这是一个经常会使用的String的无参构造函数
* 默认将“”空字符串的value赋值给实例对象的value,也是空字符串
* 相当于深拷贝了空字符串“”
*/
public String(){
    this.value = "".value;
}

/** 02
* 这是一个有参构造函数,参数为一个String对象
* 将形参的value和hash赋值给实例对象作为初始化
* 相当于深拷贝了一个形参String对象
*/
public String(String original){
    this.value = original.value;
    this.hash = original.hash;
}

/** 03
* 这是一个有参构造函数,参数为一个char字符数组
* 虽然我不知道为什么要Arrays.copyOf去拷贝,而不直接this.value = value;
* 意义就是通过字符数组去构建一个新的String对象
*/
public String(char value[]){
    this.value = Arrays.copyOf(value , value.length);
}

/** 04
* 这是一个有参构造函数,
* 使用字符数组,并指定偏移、字符个数初始化
*/
publ
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值