问题基于以下代码:
class Car implements Cloneable
{
//Relevant constructor
String name;
int wheels;
Car another;
public Object clone()
{
/*DEEP
Car n = new Car(this.name,this.wheels);
n.another = new Car(this.another.name,this.another.wheels);
return n;
*/
return super.clone() ;
}
}
main(String[] args)
{
Car c1 = new Car("merc",4);
c1.another = new Car("baby merc",55);
Car c2;
c2 = (Car)c1.clone();
//PART 1
//HERE I TRY TO CHANGE object c2's another's name to "Han"
System.out.println(c1.another.hashCode() == c2.another.hashCode());
/*POINT 1*/ c2.another.name = "Han";
System.out.println(c1.another.hashCode() == c2.another.hashCode());
//PART 2
String s = new String("gG");
System.out.println(s.hashCode());
s ="JAJA";
System.out.println(s.hashCode());
}
在第1部分中,我更改了对象
c1
的成员another
的成员名称有所不同。
在第2部分中,我创建了一个字符串,检查其哈希码,然后更改其值,然后再次检查其是否具有代码。
输出:
true
true
3264
2269358
我不明白,当我更改
c2.another.name
时c1.another.name
也指向先前的字符串“ baby merc”占用的相同的旧位置。 POINT1上的操作是否不应导致返回新的参考位置,从而导致c2.another
指向新位置,而c1.another
指向旧位置呢?当我将一个字符串指向一个新的字符串时,为什么同样的事情不会发生
串?分配堆中的新区域并引用变量
保存新位置的参考。如果是
c1
和c2
即使修改后,参考位置也不会改变!为什么?
最佳答案
c2 =(汽车)c1.clone(); // c1.another == c2.another(是的,引用是相等的,所以我使用==)
我不明白,当我更改c2.another.name时,c1.another.name也指向先前的字符串“ baby merc”占用的相同的旧位置。 POINT1上的操作不应该导致返回新的参考位置,从而导致c2.another指向新位置而c1.another指向旧位置吗?
c1和c2都共享相同的another
对象/引用。他们不关心内部的变化。第二行返回true
,因为您要更改another
内部的内容,并假设您有一盒硬币和2个人拿着它。如果您从其中取出2个硬币,则剩下的硬币对于持有此硬币的两个人都是一样的。
当我将字符串指向新字符串时,为什么没有同样的事情发生?在堆中分配了一个新区域,引用变量保存了新位置的引用。对于c1和c2,即使修改后,参考位置也不会改变!为什么?
您要创建2个不同的对象,并对其进行相同的引用(一个又一个),因此您具有2个不同的哈希码。这与克隆无关。
关于java - Java中的浅表克隆:字符串和对象表现出不同的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24742707/