在尝试理解为什么字符串是不可变的原因时,我写了一个简单的程序如下:
/* 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);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然输出不符合预期:
hello
hello world
hello world hello world hello world
hello world hello world hello world
Run Code Online (Sandbox Code Playgroud)
修改引用后,输出必须hello world test重复三次,但输出没有任何变化.
Viv*_*ath 15
它完全按预期工作.让我们一步一步地看一下:
String s = "hello";
s.concat(" world");
Run Code Online (Sandbox Code Playgroud)

这实际上是一个NOP,因为你没有将结果分配concat给任何东西.String由于没有任何内容涉及它,因此收集的以太和垃圾丢失了新实例.因此,你的s遗体不变.
s = s.concat(" world");
Run Code Online (Sandbox Code Playgroud)

这里s.concat(" world")返回一个新String实例,并重新分配s给它.所以s现在指向这个新字符串,你已经失去了对旧字符串的引用(刚才有一个字符串hello).
String s1 = s, s2 = s, s3 = s;
Run Code Online (Sandbox Code Playgroud)

在这里,您创建了三个变量,这些变量都指向指向的同一个字符串实例s.
s = s.concat(" test");
Run Code Online (Sandbox Code Playgroud)

这是您之前所做的重复.concat创建一个新的字符串实例,然后重新分配s给它.但是,请记住,s1,s2,和s3仍然指向什么s 用来指向,所以他们将不会反映更改.
你只是停止s指向旧字符串并使其指向新字符串.但是你的其他变量仍然指向那个旧字符串.
您的代码证明了字符串不变性.您可以更改变量引用的String,但是您无法更改String对象本身(除了通过我不会在这里讨论的狡猾的反射技巧).上面的错误在您的预期输出中,没有别的.例如,
s = s.concat(" test");
Run Code Online (Sandbox Code Playgroud)
创建一个新的 String对象并将其分配给s变量.它不会也不能改变所s引用的原始对象.
s被重新分配给一个新的字符串,该字符串" test" String附加到目标值的末尾String(s预分配).
s = s.concat(" test");
Run Code Online (Sandbox Code Playgroud)
这不会影响该String值存储在s1,s2或者s3,因为concat返回一个新的String对象.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |