4
class Person implements Cloneable {

    String firstName;

    public String getFirstName() {
        return firstName;
     }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public Person clone() throws CloneNotSupportedException {
            return (Person) super.clone();
        }
   }

    Person p1 = new Person();
    p1.setFirstName("P1 Sara");

    Person p3 = new Person();
    try {
        p3 = (Person) p1.clone();
    } catch (CloneNotSupportedException e) {
    }

    p3.setFirstName("cloned Sara");
    System.out.println("P3 : " + p3.getFirstName());
    System.out.println("P1: " + p1.getFirstName());

I have read that clone() method is actually a shallow copying. So, I assumed that when the value of a field in P3 is changed, the one in P1 would change too. But, that didn't happen. What am I missing here?

Sara
  • 603
  • 8
  • 19
  • Shallow copying means that they have separate fields, but those fields refer to the same instances. It's like you copying your friend's phone number to a new phone: you just have two copies of the phone number, but they call the same phone. – Andy Turner Oct 23 '18 at 11:14
  • 5
    String is an immutable type. That means that when you want to copy or clone it, you have a **new** instance of the String, with the copied value. If you change the cloned string, it does not impact the original string. – KarelG Oct 23 '18 at 11:14
  • @AndyTurner So, in this case, P3 is a clone of P1. Shouldn't they both refer to the same firstName field? – Sara Oct 23 '18 at 11:19
  • @Sara continuing the phone analogy: you have copied the phone number onto a different phone. They are storing the same thing in two places; the two phones are *not* putting things into the same phone book. If you update it in one place, it won't update in the other place. – Andy Turner Oct 23 '18 at 11:52
  • @KarelG Not exactly: cloning the object will not clone the strings: they both share the same instance, but if - after cloning - you update the original, it will just point to another string while the clone will continue to point to the initial string value. – Mark Rotteveel Oct 23 '18 at 13:42
  • @Joe That is not really a suitable duplicate, as that question concerns primitive types – Mark Rotteveel Oct 23 '18 at 13:45

1 Answers1

1

clone() method is actually a shallow copying.
Here's what happens in your example:

  1. person1 has a reference to name. Let's call this reference A. reference A point to some place in the heap memory.
  2. After you copy person1 to person3, the name reference in person3 (let's call it reference B) points to the same place in the heap memory. But it is not the same reference. It's 2 different references pointing to the same place in the heap memory.
  3. When you call p3.setFirstName("cloned Sara"), reference B is updated to point to another place in the heap memory. There is no reason for that to change the value of where reference A is pointing.
Yoav Gur
  • 1,366
  • 9
  • 15
  • Oh Ok. I am trying examples for cloning. How should I modify the Person class to truly reflect shallow copying? i.e., changes in P3 reflects in P1 and vice versa? – Sara Oct 23 '18 at 11:21
  • 1
    You could replace the `String` class, which is immutable, with a mutable class, like `StringBuilder` or `StringBuffer`, and have the setter change the value inside the mutable object, rather than use operator = that points the reference somewhere else. – Yoav Gur Oct 23 '18 at 11:24