繁体   English   中英

了解Java中的字符串不变性

[英]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了这一点。 但是请记住, s1s2s3仍指向s 指向的内容,因此它们不会反映更改。

您仅使s不再指向旧字符串,而是使其指向新字符串。 但是您的其他变量仍指向该旧字符串。

您的代码证明了字符串的不变性。 您可以更改变量所引用的String,但不能更改String对象本身(除非通过在这里不讨论的易变的反射技巧)。 上面的错误在您的预期输出中,仅此而已。 例如,

s = s.concat(" test"); 

创建一个新的 String对象并将其分配给s变量。 它没有也不会改变原来的对象s简称。

s被重新分配给一个新字符串,该String的目标String值( s预先分配)的末尾附加了" test" String

s = s.concat(" test");

这不会影响存储在s1s2s3String值,因为concat返回一个新的String对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM