【零基础 快速学Java】韩顺平 零基础30天学会Java

对于String类来说,保存字符内容的属性是private final char[] value,该属性被private修饰,无法在外部修改其值,又被final修饰,value数组的引用无法被更改。外部采用String str = new String("1234");个人理解创建对象步骤为1.现在堆中开辟空间0X11用str指向该空间。2.在0X11中在开辟空间0X22,来表示value数组的地址。3.在常量池里开辟空间0X33表示字符串1234的空间,用value数组指向该空间。如图:

所以如果要修改str的值有两种方式1.重新new一个字符串对象,那么原来的对象由于没有引用指向,就被JAVA的垃圾回收机制回收,str指向新的对象,value就是新的value,但是在常量池里的常量并未改变。2.通过常量池给str对象赋值,那么就不会再堆中开辟空间,而是判断常量池中是否要该字符串常量,如果没有在常量池中开辟一段空间来存放,在将str对象指向该空间。
特别注意:关于属性value,可能有同学还是没有弄懂到底是什么不能改,看以下例子:
final char[] value ={ 'a','b','c'}; char v[] ={ 't','o','m'}; value = v;//Cannot assign a value to final variable 'value' value[0] = 'h';
可以看到将value数组指向v数组时,会报出不能给final变量value赋值,但是value[0] = 'h'是可以的,所以value的地址不能改变但是值可以改变。但是在String类里面value是被private修饰的外部无法访问,所以我们不能像上面这个例子一样修改value的值! 所以对String对象来说,当我们重新指向新的内容时,其实本质上是开辟了新的空间,指向了新的对象。