一起养成写作习惯!这是我参与「掘金日新计划 · 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具有不变性的特性,其中主要的关键总结一下包括以下几点:
- 类使用了final修饰
- 存储内容的实际是一个byte数组,并且此byte数组使用了final、private修饰
- String内部未开放出对value修改的方法
所以平时我们在对String进行操作时,需要注意以下几点:
- String a = "1";a = "2";此时a指向的对象已经发生变化
- String b = a.replace("1","2");此时b和a是两个对象,并且a的内容不会有变化,重新打印a的值会发现a仍然为:"1"