[英]Understanding String Immutability in Java
在尝试理解字符串不可变背后的原因时,我编写了一个简单的程序,如下所示:
/* Program to test string immutability */
public class StringImmutability
{
public static void main(String args[])
{
String s = "hello";
s.concat(" world"); // returns a new string object. So, the reference must point to this object for further processing like this: s = s.concat(" world");
System.out.println(s);
s = s.concat(" world");
System.out.println(s);
String s1 = s, s2 = s, s3 = s;
System.out.println(s1+" "+s2+" "+s3);
s = s.concat(" test");
//The references are modified
System.out.println(s1+" "+s2+" "+s3);
}
}
虽然输出不符合预期:
hello
hello world
hello world hello world hello world
hello world hello world hello world
修改引用后,输出必须重复三次hello world test
但输出没有任何变化。
它的工作完全符合预期。 让我们一步一步看一下:
String s = "hello";
s.concat(" world");
这实际上是NOP,因为您没有将concat
的结果分配给任何东西。 该新的String
实例将丢失给以太并收集垃圾,因为没有任何引用。 因此,您s
保持不变。
s = s.concat(" world");
在这里s.concat(" world")
返回一个新的String
实例,并且您已将s
重新分配给它。 所以s
现在指向这个新字符串,并且您已经失去了对旧字符串(刚刚在其中hello
字符串)的引用。
String s1 = s, s2 = s, s3 = s;
在这里,您创建了三个变量,它们全部指向s
指向的同一字符串实例。
s = s.concat(" test");
这是您之前所做的重复。 concat
创建一个新字符串实例,并重新分配s
了这一点。 但是请记住, s1
, s2
和s3
仍指向s
所指向的内容,因此它们不会反映更改。
您仅使s
不再指向旧字符串,而是使其指向新字符串。 但是您的其他变量仍指向该旧字符串。
您的代码证明了字符串的不变性。 您可以更改变量所引用的String,但不能更改String对象本身(除非通过在这里不讨论的易变的反射技巧)。 上面的错误在您的预期输出中,仅此而已。 例如,
s = s.concat(" test");
创建一个新的 String对象并将其分配给s
变量。 它没有也不会改变原来的对象s
简称。
s
被重新分配给一个新字符串,该String
的目标String
值( s
预先分配)的末尾附加了" test"
String
。
s = s.concat(" test");
这不会影响存储在s1
, s2
或s3
的String
值,因为concat
返回一个新的String
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.