写点什么

String 源码解析 -String 的不变性分析

作者:zarmnosaj
  • 2022 年 5 月 09 日
  • 本文字数:766 字

    阅读完需:约 3 分钟

String 源码解析-String 的不变性分析

初步分析

最常听见的就是 String 的不变性,String 一旦 new 出来就不可更改。


此处的不可更改、不变性,指的是类一旦被初始化之后,就不能再对其值进行修改。如果进行了修改,产生的其实是一个全新的值,引用会指向这个新值。


代码举例,例如:


String string = "name";System.out.println(string);string = "age";System.out.println(string);
复制代码


表面看来,string 的值好像由"name"修改为了"age"。


但是如果从 debug 来看,或者直接看 string 的 hashcode:


System.out.println(string.hashcode());
复制代码


会发现 string 的内存地址已经改变,一个=的赋值,其实将 string 的引用指向为了一个新的 String 对象。

源码分析

看一下 String 类的声明:


public final class String implements Serializable, Comparable<String>, CharSequence
复制代码


从声明中可以看出:


String 类前有 final 修饰,final 修饰的类不能够被别的类继承,所以 String 不会有其他继承类,其中的方法也不会被重写和覆盖。


再看一下 String 的成员变量:


private final byte[] value;
复制代码


String 中存储数据的实际是一个 byte 数组,而且此数组也是被 final 修饰,所以只要 byte 数组被复制之后,value 指向的内存地址就不会再修改。并且 value 的访问修饰符是 private、String 内部也没有开放出任何对 value 可进行修改的 api。故:value 一旦被赋值之后,就不会有变化。

总结

以上,可以充分的得出 String 具有不变性的特性,其中主要的关键总结一下包括以下几点:


  1. 类使用了 final 修饰

  2. 存储内容的实际是一个 byte 数组,并且此 byte 数组使用了 final、private 修饰

  3. String 内部未开放出对 value 修改的方法


所以平时我们在对 String 进行操作时,需要注意以下几点:


  1. String a = "1";a = "2";此时 a 指向的对象已经发生变化

  2. String b = a.replace("1","2");此时 b 和 a 是两个对象,并且 a 的内容不会有变化,重新打印 a 的值会发现 a 仍然为:"1"

用户头像

zarmnosaj

关注

还未添加个人签名 2020.02.06 加入

还未添加个人简介

评论

发布
暂无评论
String源码解析-String的不变性分析_5月月更_zarmnosaj_InfoQ写作社区