个人对java中String为什么是不可变的理解

首先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
 
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

构造函数的定义

//不含参数的构造函数,一般没什么用,因为value是不可变量
public String() {
    this.value = new char[0];
}
 
//参数为String类型
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}
 
//参数为char数组,使用java.utils包中的Arrays类复制
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}
 
//从bytes数组中的offset位置开始,将长度为length的字节,以charsetName格式编码,拷贝到value
public String(byte bytes[], int offset, int length, String charsetName)
        throws UnsupportedEncodingException {
    if (charsetName == null)
        throw new NullPointerException("charsetName");
    checkBounds(bytes, offset, length);
    this.value = StringCoding.decode(charsetName, bytes, offset, length);
}
 
//调用public String(byte bytes[], int offset, int length, String charsetName)构造函数
public String(byte bytes[], String charsetName)
        throws UnsupportedEncodingException {
    this(bytes, 0, bytes.length, charsetName);
}

就模仿着对这个变量发现了一些有趣的东西。截图如下

我们知道定义一个String时是唯一的不可变得,但是我们可以在String类中修改数组中的某一个值而不是重新给整个对象赋值就像上面一样。值变了但是对象并没有变。所以这就体现了private的重要性。当我用别的类访问该类显示如下

果然报错了,这样我们就访问不到String内部定义的char数组了。当我去掉private修饰符时。

我又成功的通过其他类对这个数组进行了修改,并且数组不变。这就体现了String内部对数组进行private修饰的意义。

还有一点,String类的里面的很多属性是final的,也就是说不能通过反射来改变里面字段的值。

最后附上一篇为什么设定String是不可变得。https://blog.csdn.net/renfufei/article/details/16808775

发布了34 篇原创文章 · 获赞 11 · 访问量 9013

猜你喜欢

转载自blog.csdn.net/qq_37909141/article/details/93630997