1

我同意 String 对象是不可变的这一事实,这意味着它们不能被修改。就像下面的情况一样

String str = "Hi";
String str1 = str.concat("Nilesh");

这里如果长度参数为 0 则返回 str 对象,或者创建一个新的 String 对象并返回其引用。如果我这样做

String str = "Hi";
str="Hello";

它是如何改变的?不可变在哪里出现?请举个例子。

4

7 回答 7

5

不可变的是字符串本身,而不是指向字符串的引用。在您的第二个代码中:

String str = "hi";
str = "hello";

涉及 2 个 String 对象:"hi""hello".

str是一个引用,最初指向第一个,然后在赋值后指向第二个。但是 String 对象"hi"不会在该代码中被修改。

于 2012-09-20T12:38:11.547 回答
3

您将不变性与更改引用混淆了。

这段代码:

String str = "Hi"; // str now refers to the String "Hi"
str = "Hello";  // str now refers to the String "Hello"

只是改变所指的String对象;是一个保存对对象的引用的变量。没有发生任何改变 the或object 的事情。strstrString"Hi""Hello"


如果 String 是可变的,它会有一个类似的方法setValue(String s)可以被调用来改变它的状态,所以你可以这样做:

String str = "Hi";
str.setValue("Hello"); // if String were mutable
于 2012-09-20T12:38:02.327 回答
1

"Hello"是完全不同的对象,String所以你不能再参考"Hi"

不变性与引用无关,它与对象状态有关。如果状态改变,则创建新对象。

http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

如果一个对象在构造后它的状态不能改变,那么它就被认为是不可变的。

于 2012-09-20T12:37:49.780 回答
1

str是一个变量。术语“变量”意味着可以为变量分配各种字符串,一次一个。每个字符串仍然是不可变的。

于 2012-09-20T12:38:16.483 回答
1

如果别人说"Hello"的是另外一个String。我认为您可以看到String使用System.identityHashCode(). 试试看:

String str = "Hi";
System.out.println("try 1: "+System.identityHashCode(str));
str="Hello";
System.out.println("try 2: "+System.identityHashCode(str));

System.identityHashCode通常会返回引用本身(但你不能依赖这个事实)。

于 2012-09-20T12:41:18.033 回答
1
String str = "Hi";

str="Hello";

String是不可变的,所以我们不能修改 String 对象。

在这里,将创建两个对象,我们可以通过哈希码进行验证。

字符串 str = "你好";

System.out.println("Str(Hi)-hashcode:"+str.hashCode());

str="Hello";

System.out.println("Str(Hello)-hashcode: "+str.hashCode());

在这两种情况下,HashCode值都会不同。

第一种情况-> Str(Hi)-hashcode: 2337

第二种情况-> Str(Hello)-hashcode: 69609650

于 2015-04-17T06:29:24.767 回答
0

情况1:

String str = "Hi";
String str1 = str.concat("Nilesh");

总共创建了 3 个字符串对象

案例2:

String str = "Hi";
str="Hello";

在这种情况下,创建了 2 个字符串对象。当执行第 1 行时,str 指的是“Hi”。当执行第 2 行时,str 引用“Hello”并隔离“Hi”。str 只是指 line2 之后的“Hello”

于 2012-09-20T12:39:12.167 回答