问题基于以下代码:

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指向旧位置呢?
当我将一个字符串指向一个新的字符串时,为什么同样的事情不会发生
串?分配堆中的新区域并引用变量
保存新位置的参考。如果是c1c2
即使修改后,参考位置也不会改变!为什么?

最佳答案

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/

10-15 09:02