搞懂Java的String类的不可变性
作者:互联网
话不多说,先上源码
两个成员变量
/** The value is used for character storage. */
private final char value[];//方法大多围绕这个属性来操作
/** Cache the hash code for the string */
private int hash; // Default to 0
解释
众所周知底层是char[],再来对修饰词分析
1、final
被final修饰的变量为常量,不能被再次赋值,这里String类被实例化时,就会强制的给value[]赋值了。
//空构造器
public String() {
this.value = "".value;
}
既然为常量,表示value[]会放入常量池。
所以解释得通,面试题:new String(“abc”)创建了几个对象?(答案:一个或者两个)
首先会有个String类,而类中的value[]数组是一个对象,这是第二个对象。
第二对象的引用放在常量池里,根据final修饰的不可变性,如果有就不会再创建了。
2、private
final还不足以解决String类的不可变性,因为final修饰的是一个对象引用(再次数组是一个对象)。
即引用的指向不变,但对象里的内容可变。比如,数组虽然不能扩容(数组长度是固定的,如果要改变只能新建一个),但里面的元素可以替换,value[1]='a';。
所以,private把value[]私有化封装起来,并且不提供类似getter/setter等间接操作成员属性的方法。
可以看到String源码中的方法操作也避免操作原来的数组,而创建一个新的字符串返回。
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
//省略。。。
}
return new String(buf, true);
}
}
return this;
}
标签:Java,String,value,char,private,数组,搞懂,可变性,final 来源: https://www.cnblogs.com/InifiteVictory/p/15387042.html