1

我读了很多关于字符串对象是不可变的,只有字符串缓冲区是可变的。但是当我尝试这个程序时。我很困惑。那么这个程序中发生了什么。

class Stringss {
    public static void main(String[] args) {

        String s="hello";
        String ss=new String("xyz");
        System.out.println(ss);
        System.out.println(s);

        s="do";
        ss=new String("hello");
        System.out.println(s);
        System.out.println(ss);
    }
}

输出是

xyz
hello
do
hello
4

5 回答 5

8

在您的代码中,s不是 String 对象。它是对 String 对象的引用。您的代码使其引用了几个不同的 String 对象。但是 String 对象本身并没有改变。

例如,如果可以,String 将不是不可变的

s.setCharacterAt(3, 'Z');

或者

s.setValue("foo")

但是做

s = "a string";
s = "another string";

不会更改"a string"对象包含的内容。它只是让 s 指向另一个字符串。

打个比方,VHS 是可变的。您可以替换乐队上的内容。DVD 是不可变的:您无法更改磁盘上写入的内容。但这并不妨碍 DVD 播放器播放多张不同的 DVD。将另一张 DVD 放入 DVD 播放器不会改变 DVD 所包含的内容。

于 2013-10-05T13:25:11.567 回答
1

我认为您对 String 对象的引用和 String 对象本身之间的区别感到困惑。

当你说

String myString = "Hello";

运行时在内存“Hello”中创建一个对象。你不能直接弄乱这个对象的存储方式,因为 Java 管理内存。但是您仍然需要能够使用该对象,因此引用myString允许您以间接的方式执行此操作。

当您使用. 像这样的运算符:

myString.charAt(0)
myString.length

您正在使用您的参考来获取有关该字符串的一些信息,但您从未接触过该字符串本身。

现在它变得有点棘手。如果您接下来执行此操作:

myString = "Later";

运行时“稍后”在内存中创建一个新对象,而myString现在指向该对象。“你好”仍在记忆中,但你无法再从中获取信息。最终,Java 会弄清楚并清理它,以便您将这些内存重新用于其他事情。这表明引用可以指向任何东西,并且这些东西可以一直改变。

现在假设我想像这样更改字符串本身

myString = myString + ", dude.";

看起来您正在修改myString以向其中添加更多内容,但实际上并非如此。您在内存中有原始对象(“稍后”),运行时在内存中创建第二个对象(“,伙计。”)。然后运行时创建代表两者组合的第三个对象:“稍后,伙计。”

如果字符串是可变的(如 StringBuffer 和 StringBuilder),您可以拥有一个对象并不断更改它。但它们不是,所以每次你认为你只是在修改它时,你就是在创造新的。这可能会导致大量内存浪费,然后在运行时尝试将其全部恢复时性能下降。

所以这是关于引用和对象之间的区别。

希望有帮助。

于 2013-10-05T13:55:07.937 回答
1

这意味着每当您需要编辑字符串时,它都会创建一个全新的字符串对象,而不是修改原始对象。

于 2013-10-05T13:22:25.380 回答
0

String 是不可变的,意味着您不能修改 String 对象

以上三种方式都一样,String不是原始数据类型,它是一个类

于 2013-10-05T13:20:56.327 回答
-3

理解它的一种方法可能是这样做:

public static void main(String[] args) {
    String s="hello";
    tryToMutateString(s);
    System.out.println(s); //Will just print "hello" since our s still refers to that
}

public static void tryToMutateString(String given) {
    given += "mutated"; //Creates a new String, the string that given pointed to earlier won't change
}
于 2013-10-05T13:27:19.747 回答