str
不是一个对象,它是对一个对象的引用."Hello"
和"Help!"
是两个截然不同的String
对象.因此,str
points to是一根弦.你可以改变它points to的内容,但不能改变它points at的内容.
以下面的代码为例:
String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"
现在,我们对s1
所做的一切都不会影响s2
的值.它们指的是同一个对象——字符串"Hello"
——但该对象是不可变的,因此不能更改.
如果我们做这样的事:
s1 = "Help!";
System.out.println(s2); // still prints "Hello"
这里我们看到了改变对象和改变引用之间的区别.s2
仍然指向我们最初设置的s1
指向的同一个对象.将s1
设置为"Help!"
只会更改reference,而它最初引用的String
对象保持不变.
如果字符串是可变的,我们可以这样做:
String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"
Edit to respond to OP's edit:个
如果您查看source code for String.replace(char,char)(也可以在JDK安装目录中的src.zip中找到——一个专业提示是,每当您想知道某些东西是如何工作的时,都可以查看它),您可以看到它的功能如下:
- 如果当前字符串中出现一个或多个
oldChar
,请复制当前字符串,其中所有出现的oldChar
都替换为newChar
.
- 如果
oldChar
不在当前字符串中,请返回当前字符串.
是的,"Mississippi".replace('i', '!')
创建了一个新的String
对象.同样,以下观点成立:
String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects
你现在的作业(job)是看看如果你把s1 = s1.replace('i', '!');
改成s1 = s1.replace('Q', '!');
,上面的代码会做什么:)
1实际上,改变字符串(和其他不可变对象)是可能的.它需要反思,非常非常危险,除非你真的有兴趣销毁这个程序,否则永远不要使用它.