Java字符串的不可变性

源码

在IDEA中找到,String的源码

// Java 11
public final class String implements Serializable, Comparable<String>, CharSequence {
    @Stable
    private final byte[] value;
    private final byte coder;
    private int hash;

	private static final long serialVersionUID = -6849794470754667710L;
    ...
}
  1. String类是被final修饰的,意味着不能被继承
  2. String类实现了Serializable接口,意味着它可以被序列化;序列化可以理解为版本号的迭代,通过serialVersionUID记录。
  3. String类实现了Comparable接口,意味着最好不要使用==来比较两个字符串是否相等,应该使用compareTo()方法比较
  4. StringBuffer、StringBuilder和String一样,都实现了CharSequence接口。由于String是不可变的,所有字符串拼接的时候尽量就考虑他们。
  5. Java 9以前,String是用char数组实现的,之后改成了byte数组实现,并增加了coder来表示编码。在Latin1字符为主的程序里,可以把String占用的内存减少一般。改进在节省内存的同时也增加了编码检测的开销。
  6. 每一个字符串都有一个hash值,大概率不会重复,所以String很适合来作为HashMap的键值。

Latin1

Latin1是 ISO-8859-1 的别名,有些环境下写作Latin-1。. ISO-8859-1编码是单 字节 编码,向下兼容 ASCII ,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是 控制字符 ,0xA0-0xFF之间是文字符号。

CharSequence接口

public interface CharSequence
CharSequence是char值的可读序列。
该接口提供对许多不同类型的char序列的统一,只读访问。

CharSequence是一个描述字符串结构的接口,在这个接口里面一般发现有三种常用的子类:
(1)Stirng类
(2)StringBuffer类
(3)StringBuilder类

String的不可变性

  • String 类被 final 关键字修饰,所以它不会有子类,这就意味着没有子类可以重写它的方法,改变它的行为。
  • String 类的数据存储在 byte[] 数组中,而这个数组也被 final 关键字修饰了,这就表示 String 对象是没法被修改的,只要初始化一次,值就确定了。

为什么要这样设计?

第一,可以保证 String 对象的安全性,避免被篡改,毕竟像密码这种隐私信息一般就是用字符串存储的。

第二,保证哈希值不会频繁变更。毕竟要经常作为哈希表的键值,经常变更的话,哈希表的性能就会很差劲。

第三,可以实现字符串常量池

不管是截取、拼接,还是替换,都不是在原有的字符串上进行的,而是重新生成了新的字符串对象。也就是说,这些操作执行过后,原来的字符串对象并没有发生改变。

String 对象一旦被创建后就固定不变了,对 String 对象的任何修改都不会影响到原来的字符串对象,都会生成新的字符串对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值