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

155 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

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"