我读了很多字符串对象是不可变的,只有字符串缓冲区是可变的。但是当我尝试这个程序时。我很迷惑。那么这个计划到底发生了什么。
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
答案 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
}