考虑下面的例子。
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指向不同的对象?
Java中的String在Immutable和Final中只是意味着它不能被更改或修改:
案例1:
class TestClass{
public static void main(String args[]){
String str = "ABC";
str.concat("DEF");
System.out.println(str);
}
}
输出:美国广播公司(ABC)
原因:对象引用str没有改变,实际上是一个新对象
在池中创建了“DEF”,它根本没有引用
(也就是失去了)。
案例2:
class TestClass{
public static void main(String args[]){
String str="ABC";
str=str.concat("DEF");
System.out.println(str);
}
}
输出:六边形ABCDEF
原因:在这种情况下,str现在引用一个新对象“ABCDEF”
因此它打印ABCDEF,即前一个str对象“ABC”在池中丢失,没有引用。
字符串类是不可变的,你不能改变不可变对象的值。
但在String的情况下,如果你改变了String的值,它会在字符串池中创建新的字符串,而不是旧的字符串引用。通过这种方式,字符串是不可变的。
举个例子,
String str = "Mississippi";
System.out.println(str); // prints Mississippi
它将创建一个字符串“Mississippi”,并将其添加到字符串池
所以现在str指向密西西比。
str = str.replace("i", "!");
System.out.println(str); // prints M!ss!ss!pp!
但经过上述操作,
另一个字符串将被创建"M!ss!ss!pp!"
它将被添加到String池。而且
现在str指向M!ss!ss!pp!而不是密西西比州。
通过这种方式,当你改变string对象的值时,它会创建一个新的对象并将其添加到string池中。
让我们再看一个例子
String s1 = "Hello";
String s2 = "World";
String s = s1 + s2;
上面的3行代码将向字符串池中添加3个字符串对象。
1)你好
2)世界
3) HelloWorld
我会用一个简单的例子来解释
考虑任何字符数组:例如char[] ={‘h’,‘e’,‘l’,‘l’,”o '};
和一个字符串:
字符串s =“你好”;
在字符数组上,我们可以执行如下操作:使用迭代数组只打印最后三个字母;
但在字符串中,我们必须创建新的字符串对象并复制所需的子字符串,其地址将在新的字符串对象中。
e.g.
***String s="hello";
String s2=s.substrig(0,3);***
s2有“hel”;
Java中的String在Immutable和Final中只是意味着它不能被更改或修改:
案例1:
class TestClass{
public static void main(String args[]){
String str = "ABC";
str.concat("DEF");
System.out.println(str);
}
}
输出:美国广播公司(ABC)
原因:对象引用str没有改变,实际上是一个新对象
在池中创建了“DEF”,它根本没有引用
(也就是失去了)。
案例2:
class TestClass{
public static void main(String args[]){
String str="ABC";
str=str.concat("DEF");
System.out.println(str);
}
}
输出:六边形ABCDEF
原因:在这种情况下,str现在引用一个新对象“ABCDEF”
因此它打印ABCDEF,即前一个str对象“ABC”在池中丢失,没有引用。