解释一下,字符串是不可变的

时间:2013-10-05 13:20:09

标签: java string immutability

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

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

5 个答案:

答案 0 :(得分:8)

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

如果可以的话,字符串将不是不可变的,例如

s.setCharacterAt(3, 'Z');

s.setValue("foo")

但是在做

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

不会更改"a string"对象包含的内容。它只是指向另一个String。

作为类比,VHS是可变的。你可以替换乐队的内容。 DVD是不可变的:您无法更改磁盘上正在写入的内容。但这并不妨碍DVD播放机播放几种不同的DVD。将另一张DVD放入DVD播放机内并不会改变DVD所包含的内容。

答案 1 :(得分:1)

这意味着无论何时需要编辑String,它都会创建一个全新的String对象,而不是修改原始对象。

答案 2 :(得分:1)

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

当你说

String myString = "Hello";

运行时在内存中创建一个对象" Hello。"由于Java管理内存,因此您无法直接处理此对象的存储方式。但您仍然需要能够使用该对象,因此引用 myString 可以让您以间接方式执行此操作。

当您使用 myString 进行调用时。像这样的运营商:

myString.charAt(0)
myString.length

您正在使用您的引用来获取有关该字符串的一些信息,但您从不触及字符串本身。

现在有点棘手。如果你接下来这样做:

myString = "Later";

运行时在内存中创建一个新对象"稍后,"而 myString 现在指向了它。 "你好"仍然坐在记忆中,但你无法再从中获取信息。最终,Java会解决这个问题并将其清理干净,以便将内存恢复到其他状态。这表明引用可以指向任何东西,而这些东西可以随时改变。

现在让我们说要像这样更改字符串本身

myString = myString + ", dude.";

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

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

所以它是关于参考和对象之间的区别。

希望有所帮助。

答案 3 :(得分:0)

字符串是不可变的意味着您无法修改String对象

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

答案 4 :(得分:-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
}