Q:

How exactly does object.clone() work in java?

I am trying to understand the working of clone() method of Object class.
The comment in Object class says 'this method performs a "shallow copy" of this object, not a "deep copy" operation.'
Following is my understanding on Shallow & Deep copy..

Shallow copies duplicate as little as possible. A shallow copy of a
  collection is a copy of the collection structure, not the elements.
  With a shallow copy, two collections now share the individual
  elements.
Deep copies duplicate everything. A deep copy of a collection is two
  collections with all of the elements in the original collection
  duplicated.

So if I clone an Object and modifies any of its mutable elements on the clone, same should get reflected on the first object from which the clone is created since both share the same memory. To test this, I created 3 classes...
A simple pojo..
package test.clone;

import java.util.Arrays;

public class Misc implements Cloneable{
    private String value;

    public Misc(String value) {
        super();
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Misc [value=" + value + "]";
    }

    protected Misc clone() throws CloneNotSupportedException{
        return (Misc)super.clone();
    }

}

Class that need to be cloned..
package test.clone;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Victim implements Cloneable{
    private String name = "Renjith";
    private String[] educationList = {"EDU_1", "EDU_2", "EDU_3", "EDU_4"};
    private Misc[] miscList = {new Misc("1"), new Misc("2")};
    private List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String[] getEducationList() {
        return educationList;
    }
    public void setEducationList(String[] educationList) {
        this.educationList = educationList;
    }

    protected Victim clone() throws CloneNotSupportedException{
        return (Victim)super.clone();
    }
    public Misc[] getMiscList() {
        return miscList;
    }
    public void setMiscList(Misc[] miscList) {
        this.miscList = miscList;
    }

    public List<Misc> getMiscList2() {
        return miscList2;
    }
    public void setMiscList2(List<Misc> miscList2) {
        this.miscList2 = miscList2;
    }
    @Override
    public String toString() {
        return "Victim [name=" + name + ", educationList="
                + Arrays.toString(educationList) + ", miscList="
                + Arrays.toString(miscList) + ", miscList2=" + miscList2 + "]";
    }

}

Main class that does the cloning.... and modification...
public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {
        Victim victim = new Victim();

        System.out.println(victim);

        Victim secondVictim = victim.clone();

        String[] educationList = {"EDU_1_mod", "EDU_2_mod", "EDU_3_mod", "EDU_4_mod"};
        Misc[] miscList = {new Misc("3"), new Misc("4")};
        List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));

        secondVictim.setEducationList(educationList);
        secondVictim.setMiscList(miscList);
        secondVictim.setMiscList2(miscList2);

        System.out.println(secondVictim);

        System.out.println(victim);
    }

}

I was expecting an output as follows...

Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4],
  miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1],
  Misc [value=2]]] Victim [name=Renjith, educationList=[EDU_1_mod,
  EDU_2_mod, EDU_3_mod, EDU_4_mod], miscList=[Misc [value=3], Misc
  [value=4]], miscList2=[Misc [value=3], Misc [value=4]]] Victim
  [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4],
  miscList=[Misc [value=3], Misc [value=4]], miscList2=[Misc [value=3],
  Misc [value=4]]]

But I got...

Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4],
  miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1],
  Misc [value=2]]] Victim [name=Renjith, educationList=[EDU_1_mod,
  EDU_2_mod, EDU_3_mod, EDU_4_mod], miscList=[Misc [value=3], Misc
  [value=4]], miscList2=[Misc [value=3], Misc [value=4]]] Victim
  [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4],
  miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1],
  Misc [value=2]]]

Can any one tell me what is wrong with this??
I have gone through Understanding Object.clone() in Java, but still not able to understand ....

A:

You're not modifying the lists/arrays, you're replacing them with a new reference. Try updating your setters like this:
public void setMiscList(Misc[] miscList) {
    this.miscList[0] = miscList[0];
    this.miscList[1] = miscList[1];
}

public void setMiscList2(List<Misc> miscList2) {
    this.miscList2.set(0, miscList2.get(0));
    this.miscList2.set(1, miscList2.get(1));
}

This should modify the shared objects, resulting in your expected output.

