真的了解String 不可变?
String 的确不可变
面试:String 为什么是不可变的?
回答: 因为String类中使用了final 关键字修饰所以不可变 。
面试: 嗯嗯,你可以回去了,欢迎下次再来。
public static void main(String[] args) {
final char[] charsList={'c','h','a','r'};
String a=new String(charsList);
changeSomeone(a,charsList);
System.out.println(a);
System.out.println(charsList);
}
public static void changeSomeone (String s,char[] charList){
s="shar";
charList[0]='s';
}
// 输出
//char
//shar
以上代码 执行想改变 String 和 char[] 两个引用类型 ,结果发现String 是不变的。
- “String类中使用了final 关键字修饰所以不可变” 只是原因之一。是为了防止String 不被继承(被外部修改String)。
String的具体实现
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
//之前是 private final char value[]; java9 后改 byte[] 节省一半的内存空间,缓解gc压力
private final byte[] value;
- 真正储存字符内容的是 byte[] 数组,而private 打出了神助攻,大家有没有发现 在String 源码中 访问权限控制极为苛刻 ,private防止其它访问(只能被自己访问和修改)并且 在String类内部也没提供方法来修改这个byte[] 数组。 (注意上面代码 被final修饰的是 引用类型,当final 修饰 基础类型是值不变,而修饰引用类型的时候是引用类型时,引用指向对象的地址是不可变的 ,但引用指向对象的内容可变的)
总结
所以 String不可变的原因是
- String无法被继承修改
- String 内部真正储存的是 byte[] value被 final 修饰且为私有的 ,内部无提供 修改操作该数组的方法。(外部无权限,内部无机会)