M
mingclee1
Hello,
I have a question with clone() in java collection. Check the following
code:
import java.util.*;
/**
* @author mlee45
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class TestClone implements Cloneable {
private Entry[] inner_a1 = {new Entry(1), new Entry(2)};
private Entry[] inner_a2 = {new Entry(3), new Entry(4)};
public Object[] a1 = {new Entry(5), new Entry(6)};
public Object[] a2 = {inner_a1, inner_a2};
public ArrayList v1, v2 = new ArrayList();
public TestClone(){
initialize();
}
private void initialize(){
v1 = new ArrayList();
v1.add(0, new Entry(5));
v1.add(1, new Entry(6));
v2.add(0, inner_a1);
v2.add(1, inner_a2);
}
public Object clone() throws CloneNotSupportedException{
TestClone result = (TestClone)super.clone();
result.v1 = (ArrayList)v1.clone();
result.v2 = (ArrayList)v2.clone();
result.a1 = (Object[])a1.clone();
result.a2 = (Object[])a2.clone();
return result;
}
public static void main(String[] args){
TestClone tc = new TestClone();
try{
TestClone tc_2 = (TestClone)tc.clone();
tc_2.v1.set(0, new Entry(10));
//**************** test arrayList *******************
System.out.println("tc.v1[0] is"+tc.v1.get(0));
System.out.println("tc_2.v1[0] is"+tc_2.v1.get(0));
Entry[] inner_a3 = { new Entry(10), new Entry(11)};
tc_2.v2.set(0, inner_a3);
Entry[] e1 = (Entry[])tc.v2.get(0);
Entry[] e2 = (Entry[])tc_2.v2.get(0);
System.out.println("e1[0] is "+e1[0]);
System.out.println("e2[0] is "+e2[0]);
//******************** test array ********************
tc.a1[0] = new Entry(100);
System.out.println("tc.a1[0] is "+tc.a1[0]);
System.out.println("tc_2.a1[0] is "+tc_2.a1[0]);
Entry[] inner_a4 = {new Entry(1000), new Entry(1001)};
tc_2.a2[0] = inner_a4;
e1 = (Entry[])tc.a2[0];
e2 = (Entry[])tc_2.a2[0];
System.out.println("tc.a2[0] is "+e1[0]);
System.out.println("tc_2.a2[0] is "+e2[0]);
}catch(CloneNotSupportedException ce){
ce.printStackTrace();
}
}
}
class Entry{
int val;
public Entry(int _val){
val = _val;
}
public String toString(){
return Integer.toString(val);
}
}
The output is
tc.v1[0] is5
tc_2.v1[0] is10
e1[0] is 1
e2[0] is 10
tc.a1[0] is 100
tc_2.a1[0] is 5
tc.a2[0] is 1
tc_2.a2[0] is 1000
Question: It seems that clone() method called on array does a deep
copy instead of the default shallow copy. Is this an internal special
condition? Also, I tried to use both Vector and ArrayList, I got the
same result from both. I checked the API, it says clone() method for
vector is deep copy which explains my result, but clone() method for
ArrayList returns a shallow copy which doesn't explain my result? It
seems that any out of the box collection with out of the box clone()
method does deep copy?
Also, it was interesting to know that if I make the array or vector
defined above static, the call to clone() would still work, but result
would show only one object is created. Shouldn't it throw
CloneNotSupportedException like in final?
Thanks for your advice!
I have a question with clone() in java collection. Check the following
code:
import java.util.*;
/**
* @author mlee45
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class TestClone implements Cloneable {
private Entry[] inner_a1 = {new Entry(1), new Entry(2)};
private Entry[] inner_a2 = {new Entry(3), new Entry(4)};
public Object[] a1 = {new Entry(5), new Entry(6)};
public Object[] a2 = {inner_a1, inner_a2};
public ArrayList v1, v2 = new ArrayList();
public TestClone(){
initialize();
}
private void initialize(){
v1 = new ArrayList();
v1.add(0, new Entry(5));
v1.add(1, new Entry(6));
v2.add(0, inner_a1);
v2.add(1, inner_a2);
}
public Object clone() throws CloneNotSupportedException{
TestClone result = (TestClone)super.clone();
result.v1 = (ArrayList)v1.clone();
result.v2 = (ArrayList)v2.clone();
result.a1 = (Object[])a1.clone();
result.a2 = (Object[])a2.clone();
return result;
}
public static void main(String[] args){
TestClone tc = new TestClone();
try{
TestClone tc_2 = (TestClone)tc.clone();
tc_2.v1.set(0, new Entry(10));
//**************** test arrayList *******************
System.out.println("tc.v1[0] is"+tc.v1.get(0));
System.out.println("tc_2.v1[0] is"+tc_2.v1.get(0));
Entry[] inner_a3 = { new Entry(10), new Entry(11)};
tc_2.v2.set(0, inner_a3);
Entry[] e1 = (Entry[])tc.v2.get(0);
Entry[] e2 = (Entry[])tc_2.v2.get(0);
System.out.println("e1[0] is "+e1[0]);
System.out.println("e2[0] is "+e2[0]);
//******************** test array ********************
tc.a1[0] = new Entry(100);
System.out.println("tc.a1[0] is "+tc.a1[0]);
System.out.println("tc_2.a1[0] is "+tc_2.a1[0]);
Entry[] inner_a4 = {new Entry(1000), new Entry(1001)};
tc_2.a2[0] = inner_a4;
e1 = (Entry[])tc.a2[0];
e2 = (Entry[])tc_2.a2[0];
System.out.println("tc.a2[0] is "+e1[0]);
System.out.println("tc_2.a2[0] is "+e2[0]);
}catch(CloneNotSupportedException ce){
ce.printStackTrace();
}
}
}
class Entry{
int val;
public Entry(int _val){
val = _val;
}
public String toString(){
return Integer.toString(val);
}
}
The output is
tc.v1[0] is5
tc_2.v1[0] is10
e1[0] is 1
e2[0] is 10
tc.a1[0] is 100
tc_2.a1[0] is 5
tc.a2[0] is 1
tc_2.a2[0] is 1000
Question: It seems that clone() method called on array does a deep
copy instead of the default shallow copy. Is this an internal special
condition? Also, I tried to use both Vector and ArrayList, I got the
same result from both. I checked the API, it says clone() method for
vector is deep copy which explains my result, but clone() method for
ArrayList returns a shallow copy which doesn't explain my result? It
seems that any out of the box collection with out of the box clone()
method does deep copy?
Also, it was interesting to know that if I make the array or vector
defined above static, the call to clone() would still work, but result
would show only one object is created. Shouldn't it throw
CloneNotSupportedException like in final?
Thanks for your advice!