考虑下面的例子。

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

在Java中,String对象是不可变的。那么为什么对象str可以被赋值为"Help!"呢?这难道不是与Java中字符串的不变性相矛盾吗?有人能给我解释一下不变性的确切概念吗?

编辑:

好的。我现在明白了,但还有一个问题。下面的代码呢:

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

这是否意味着将再次创建两个对象(“Mississippi”和“M!ss!ss!pp!”),并且在replace()方法之后引用str指向不同的对象?


当前回答

我会用一个简单的例子来解释


考虑任何字符数组:例如char[] ={‘h’,‘e’,‘l’,‘l’,”o '}; 和一个字符串: 字符串s =“你好”;


在字符数组上,我们可以执行如下操作:使用迭代数组只打印最后三个字母; 但在字符串中,我们必须创建新的字符串对象并复制所需的子字符串,其地址将在新的字符串对象中。

e.g.

***String s="hello";
String s2=s.substrig(0,3);***

s2有“hel”;

其他回答

我建议你读一读《Cup Size》——一个关于变量和值传递的故事(续《Cup Size》)。这对阅读上面的文章有很大帮助。

你读过吗?是的。好。

String str = new String();

这将创建一个名为“str”的新“远程控制”,并将其设置为值new String()(或“”)。

例如,在内存中创建:

str --- > ""

str  = "Hello";

这将更改远程控制“str”,但不会修改原始字符串“”。

例如,在内存中创建:

str -+   ""
     +-> "Hello"

str = "Help!";

这将更改远程控件“str”,但不会修改原始字符串“”或远程控件当前指向的对象。

例如,在内存中创建:

str -+   ""
     |   "Hello"
     +-> "Help!"

在Java中,对象通常是通过引用访问的。在你的代码段中,str是一个引用,它首先被赋值给“Hello”(一个自动创建的对象或从常量池中获取的对象),然后你将另一个对象“Help!”赋值给同一个引用。需要注意的一点是,引用是相同的,但对象是不同的。代码中还有一件事,你访问了三个对象,

当你调用new String()。 当你分配"hello"的时候。 当你说“救命!”

调用new String()会创建一个新对象,即使它存在于字符串池中,所以通常不应该使用它。要将new string()创建的字符串放入字符串池,可以尝试intern()方法。

我希望这能有所帮助。

我会用一个简单的例子来解释


考虑任何字符数组:例如char[] ={‘h’,‘e’,‘l’,‘l’,”o '}; 和一个字符串: 字符串s =“你好”;


在字符数组上,我们可以执行如下操作:使用迭代数组只打印最后三个字母; 但在字符串中,我们必须创建新的字符串对象并复制所需的子字符串,其地址将在新的字符串对象中。

e.g.

***String s="hello";
String s2=s.substrig(0,3);***

s2有“hel”;

或者你可以试试:

public class Tester
{
public static void main(String[] args)
{
 String str = "Mississippi"; 
 System.out.println(str); // prints Mississippi 
 System.out.println(str.hashCode());

 str = str.replace("i", "!"); 
 System.out.println(str); // prints M!ss!ss!pp! 
 System.out.println(str.hashCode());
 }
 }

这将显示hashcode是如何变化的。

我可以说,不可变性是你不能改变字符串本身。假设你有字符串x,它的值是“abc”。现在您不能更改字符串,也就是说,您不能更改“abc”中的任何字符/s。

如果你必须改变字符串中的任何字符,你可以使用一个字符数组并改变它或使用StringBuilder。

String x = "abc";
x = "pot";
x = x + "hj";
x = x.substring(3);
System.out.println(x);

char x1[] = x.toCharArray();
x1[0] = 's';
String y = new String(x1);
System.out.println(y);

输出:

hj
sj