Reputation: 1144
Questions are based on the following code :
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());
}
c1
's member another
's member name
to be different. Output :
true
true
3264
2269358
c2.another.name
then
c1.another.name
also points to that same exact old location that the previous string "baby merc" had occupied. Shouldn't the operation at POINT1 cause a new reference location to be returned thus resulting in c2.another
pointing to a new location while c1.another
points to the old?c1
and c2
the reference location doesn't change even after modification! Why?Upvotes: 0
Views: 381
Reputation: 311
Whenever a clone() method is called on an object that contains members of any class type, then only reference variables to those members are copied.
That's why when the following statement is executed:
c2 = (Car)c1.clone();
A new object is created in the heap for c2, it contains a reference to the object another. C1 also contains reference to another. Now both c1 and c2 has reference variables that point to another. Therefore both c1 and c2 can modify the state of another.
In the case of String, a new area is allocated in the heap,
whenever you use a 'new' keyword to create a String object
When you create a string literal, and that string does not exist in the string pool so far.
Upvotes: 0
Reputation: 36304
c2 = (Car)c1.clone(); // c1.another == c2.another (yes, the references are equal, so I am using ==)
I don't understand that when I change c2.another.name then c1.another.name also points to that same exact old location that the previous string "baby merc" had occupied. Shouldn't the operation at POINT1 cause a new reference location to be returned thus resulting in c2.another pointing to a new location while c1.another points to the old?
Both c1 and c2 share the same another
object / reference. They are not concerned about what changes inside it. The second line returns true
because you are changing something inside another
, assume that you have a box of coins and 2 people holding it. If you remove 2 coins from it, the remaining coins will be the same for both people holding it.
And why does the same not happen when I make a string point to a new string? A new area in heap is allocated and the reference variable holds the reference of the new location. In case of c1 and c2 the reference location doesn't change even after modification! Why?
You are creating 2 different objects and making the same reference point to it (one after another), so you have 2 different hash codes. This has got nothing to do with cloning.
Upvotes: 1
Reputation: 43728
c1.another
is the same object as c2.another
, therefore they will always have exactly the same hash code.
Moreover, the standard hash code is based on the objects identity. Changing the fields of the object does not change its hash code.
Upvotes: 1