[英]Understanding String Immutability in Java
While trying the understand the reasons behind why strings are immutable, I wrote a simple program as follows: 在尝试理解字符串不可变背后的原因时,我编写了一个简单的程序,如下所示:
/* 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);
}
}
The output though isn't as expected: 虽然输出不符合预期:
hello
hello world
hello world hello world hello world
hello world hello world hello world
After the references are modified, the output must be hello world test
repeated thrice but there isn't any change in output. 修改引用后,输出必须重复三次hello world test
但输出没有任何变化。
It is working exactly as expected. 它的工作完全符合预期。 Let's look at it step by step: 让我们一步一步看一下:
String s = "hello";
s.concat(" world");
This is effectively a NOP because you are not assigning the result of concat
to anything. 这实际上是NOP,因为您没有将concat
的结果分配给任何东西。 That new String
instance is lost to the ether and garbage collected since there is nothing referring to it. 该新的String
实例将丢失给以太并收集垃圾,因为没有任何引用。 Hence, your s
remains unchanged. 因此,您s
保持不变。
s = s.concat(" world");
Here s.concat(" world")
returns a new String
instance, and you have reassigned s
to that. 在这里s.concat(" world")
返回一个新的String
实例,并且您已将s
重新分配给它。 So s
now points to this new string and you have lost the reference to the older one (the one that just had hello
in it). 所以s
现在指向这个新字符串,并且您已经失去了对旧字符串(刚刚在其中hello
字符串)的引用。
String s1 = s, s2 = s, s3 = s;
Here you have created three variables that all point to the same string instance that s
points to. 在这里,您创建了三个变量,它们全部指向s
指向的同一字符串实例。
s = s.concat(" test");
This is a repeat of what you did earlier. 这是您之前所做的重复。 concat
creates a new string instance and you reassign s
to that. concat
创建一个新字符串实例,并重新分配s
了这一点。 But keep in mind that s1
, s2
, and s3
are still pointing to what s
used to point to and so they will not reflect the changes. 但是请记住, s1
, s2
和s3
仍指向s
所指向的内容,因此它们不会反映更改。
You've only stopped s
from pointing to the old string and made it point to the new one. 您仅使s
不再指向旧字符串,而是使其指向新字符串。 But your other variables are still pointing to that old string. 但是您的其他变量仍指向该旧字符串。
Your code proves String immutability. 您的代码证明了字符串的不变性。 You can change the String that a variable refers to, but you can't change the String object itself (other than through shifty reflection tricks that I won't discuss here). 您可以更改变量所引用的String,但不能更改String对象本身(除非通过在这里不讨论的易变的反射技巧)。 The error above is in your expected output and nothing else. 上面的错误在您的预期输出中,仅此而已。 For example, 例如,
s = s.concat(" test");
creates a new String object and assigns it to the s
variable. 创建一个新的 String对象并将其分配给s
变量。 It does not and cannot change the original object that s
referred to. 它没有也不会改变原来的对象s
简称。
s
is reassigned to a new string that has the " test"
String
appended to the end of the target String
value ( s
pre-assignment). s
被重新分配给一个新字符串,该String
的目标String
值( s
预先分配)的末尾附加了" test"
String
。
s = s.concat(" test");
This does not affect the String
value stored in s1
, s2
, or s3
, since concat
returns a new String
object. 这不会影响存储在s1
, s2
或s3
的String
值,因为concat
返回一个新的String
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.