来自oracle doc
字符串是immutable字符串也是常量;他们的价值观 创建后无法更改。因为他们是 不可变的他们可以共享。字符串缓冲区支持可变字符串。
但我总能做到以下几点:
String name="SO";
name="SE";
我可以更改值,所以它如何是不可变的,据说出于安全原因也喜欢数据库连接等。
请原谅我提出这样的基本问题,但我需要了解。
答案 0 :(得分:4)
name="SE"
通过这样做,您正在更改name
变量的值,而不是String对象SO
本身。字符串在某种意义上是不可变的,String对象SO
一旦创建就无法修改。通过执行name = name+"TEST";
,将在内存中创建一个新的String对象SOTEST
,而不会修改现有的String对象SO
。
答案 1 :(得分:1)
在您提供的示例中,您创建了两个String
。首先创建String
SO
,并将引用分配给name
。然后创建新的String
SE
,并将该引用分配给name
。您从未真正修改过创建的第一个String
。
String temp = "SO";
String name = temp;
name = "SE";
System.out.println(temp.equals("SO")); //prints true;
System.out.println(temp == name); //compares references prints false
答案 2 :(得分:1)
是的,您可以更改name
变量指向的字符串。但是,让我们看看执行以下代码序列时会发生什么:
String name = "SO"; //line 1
name = "SE"; //line 2
在第1行:创建一个新的String对象,其中包含值“SO”;
在第2行:创建一个新的String对象,它保存值“SE”;您的name
变量值会发生变化,因为它指向另一个引用,即第二个String对象;第一个String对象(“SO”)仍然在堆上,但不再被引用,并且可用于将来的垃圾收集(如果有的话)。
这里你要理解的是,只要构造了包含char序列{'S','O'}的String对象,该String对象包装的char序列就永远不会再改变。例如。你不能使该对象包装char序列{'S','E'}。这就是不变性所在。
答案 3 :(得分:1)
当您更改String引用的值时,实际上创建新对象。现在您的引用将链接到此新对象。
String myValue = "old";
- > VM创建String对象“old”
myValue = "new";
- > VM创建了String对象“new”; “旧”对象仍然存在,但任何引用都链接到此,所以我们可以说:“旧”丢失
答案 4 :(得分:1)
例如,请参阅internet中的下图:
大云是存储对象的堆,s是对象的引用(在您的问题中,您使用名称作为参考)
当你执行s =“abcd”时,会在堆中创建一个新对象,s是对它的引用。 (如上箭头所示)
重点:
当你执行类似s =“abcdef”或s = s +“ef”之类的操作时,不能更改不可变字符串对象“abcd”,因此会创建一个新对象并失去它对旧字符串的引用(显示用虚线表示)现在引用新的String(由底部箭头显示)。
我认为旧的对象在某些时候被垃圾收集器拾取。