fatherazrael
fatherazrael

Reputation: 5977

Java: Shallow Copy (Cloning) not working for me?

As per definition:

A shallow copy is one in which we only copy values of fields from one object to another. They are different objects, but the problem is that when we change any of the original address' properties, this will also affect the shallowCopy‘s address.

I tried to see if value of object 1 and object 2 becomes same so tried following and not able to do so.

public class TestClone implements Cloneable {
    private String a;

    public String getA() {
        return a;
    }


    public void setA(String a) {
        this.a = a;
    }


    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Main Program:

package com.test;

public class MainTestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        TestClone clone = new TestClone();
        clone.setA("RABA");

        TestClone clone2 = (TestClone) clone.clone();
        System.out.println(clone.getA());
        System.out.println(clone2.getA());
        System.out.println("---------------------------");
        clone.setA("DABA");
        System.out.println(clone.getA());
        System.out.println(clone2.getA());
        System.out.println("---------------------------");
        clone2.setA("Clone2 RABA DABA");
        System.out.println(clone.getA());
        System.out.println(clone2.getA());

    }
}

Output:

RABA
RABA
---------------------------
DABA
RABA <--- It does not change to DABA
---------------------------
DABA <--- No Changes here
Clone2 RABA DABA

Upvotes: 1

Views: 640

Answers (4)

Anishek Raman Bharti
Anishek Raman Bharti

Reputation: 179

Whatever you have implemented is Shallow copying only . Changing the attribute of an original object is not affecting the state of copy object because it only contain immutable fields. If it had contained any mutable object, it would have affected both of them .

If you try adding another field of any Class type and the try changing value of field of that class , then changes will be reflected in clone as well as clone2 objects .

Upvotes: 1

Stephen C
Stephen C

Reputation: 718826

I think that the real problem is that you have taken the following definition out of context and are misinterpreting it:

"A shallow copy is one in which we only copy values of fields from one object to another. They are different objects, but the problem is that when we change any of the original address' properties, this will also affect the shallowCopy‘s address."

This is clearly referring to some example ... which you have not quoted. (Hence my comment that you have taken it out of context!)

For this description to be correct, the "original address' properties" must be fields separate objects to the one that you are cloning. I imagine that the example is something like this:

public class User implements Cloneable {
    String name;
    Address address; 
    ...
    public User clone() {
        return (User)(super.clone());
    }
}

public class Address {
    String street;
    String city;
    String zipCode;
}

and they are doing this:

Address address = new Address(...);
User user = new User("Fred", address);
User shallowCopy = user.clone();

and then

user.getAddress().setZipCode(...);

and observing that this changes the zip code associated with both the original and the cloned User objects.

Note we are changing properties of the Address rather than properties of the User. As the quoted text is clearly saying.


But your example is different. In that you are (respectively) changing a field of the original and cloned objects. And observing that assigning one does not affect the other.

What you are doing is equivalent to

shallowCopy.setAddress(new Address(...));

If you did that, then the object that shallowCopy refers to will no longer be a shallow copy of the object that user refers to, and user.getAddress().setZipCode(...) will no longer affect the zip code of shallowCopy or vice versa.

In short, the reason that you are seeing something different to what the definition says is that you are doing something different.

Clone is working exactly as specified. The problem is that you have misinterpretted or misapplied the definition of shallow copy.

Upvotes: 2

CodeScale
CodeScale

Reputation: 3304

Shallow copy is about sharing internal references. If you change the reference directly the clone will stay on the old reference because it is a different object.

That’s why the name shallow copy or shallow cloning in Java. If only primitive type fields or Immutable objects are there then there is no difference between shallow and deep copy in Java. That's why here you have actually a deep copy.

If you replace String by Date for instance and then modify the date content (not the reference..the content like this obj1.date().setTime(1) the clone object will reflect the change because it points to the same Date reference.

We could see copies like this

On shallow copy clone2.date = clone.date

On deep copy clone2.date=new Date(clone.getTime());

Upvotes: 1

QuickSilver
QuickSilver

Reputation: 4045

super.clone

as per Java Docs

Creates and returns a copy of this object.

hence whatever changes you do to old object would be independent of the newly cloned object. So clone , clone2 are separate Java Objects saved in different memory space.

if you are looking replicate the changes to clone2 point both the ref to same object. for e.g

TestClone clone2 = clone;

Upvotes: 0

Related Questions