在自定义类Person中,会有Collection集合类型。
下面我就不一步步测试给大家看了,我就直接贴出来正确的clone方法了。
目前针对,ArrayList<String>, ArrayList<Integer>这两个类型。
package tt.vo;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
public class Person implements Cloneable {
// 基本数据类型
private int age;
// Wrapper Class类型
private Integer height;
// String 类型
private String name;
// StringBuffer
private StringBuffer address1;
// StringBuilder
private StringBuilder address2;
// Date
private Date date;
// Timestamp
private Timestamp timestamp;
// int array
private int[] intArray;
// Integer Array
private Integer[] integerArray;
// String Array
private String[] stringArray;
private ArrayList<String> stringList;
private ArrayList<Integer> integerList;
@Override
public Person clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
// StringBuffer,StringBuilder 没有实现clone方法
// 只能用 new, 去完成克隆动作
if (this.address1 != null) {
p.address1 = new StringBuffer(this.address1);
}
if (this.address2 != null) {
p.address2 = new StringBuilder(this.address2);
}
if (this.date != null) {
p.date = (Date) this.date.clone();
}
if (this.timestamp != null) {
p.timestamp = (Timestamp) this.timestamp.clone();
}
if (this.intArray != null) {
p.intArray = this.intArray.clone();
}
if (this.integerArray != null) {
p.integerArray = this.integerArray.clone();
}
if (this.stringArray != null) {
p.stringArray = this.stringArray.clone();
}
// list clone 要强转类型, 此处是对list的浅克隆
if (this.stringList != null) {
p.stringList = (ArrayList<String>) this.stringList.clone();
}
if (this.integerList != null) {
p.integerList = (ArrayList<Integer>) this.integerList.clone();
}
return p;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public StringBuffer getAddress1() {
return address1;
}
public void setAddress1(StringBuffer address1) {
this.address1 = address1;
}
public StringBuilder getAddress2() {
return address2;
}
public void setAddress2(StringBuilder address2) {
this.address2 = address2;
}
@Override
public String toString() {
return "Person [age=" + age + ", height=" + height + ", name=" + name
+ ", address1=" + address1 + ", address2=" + address2
+ ", date=" + date + ", timestamp=" + timestamp + ", intArray="
+ Arrays.toString(intArray) + ", integerArray="
+ Arrays.toString(integerArray) + ", stringArray="
+ Arrays.toString(stringArray) + ", stringList=" + stringList
+ ", integerList=" + integerList + "]";
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public Integer[] getIntegerArray() {
return integerArray;
}
public void setIntegerArray(Integer[] integerArray) {
this.integerArray = integerArray;
}
public String[] getStringArray() {
return stringArray;
}
public void setStringArray(String[] stringArray) {
this.stringArray = stringArray;
}
public int[] getIntArray() {
return intArray;
}
public void setIntArray(int[] intArray) {
this.intArray = intArray;
}
public ArrayList<String> getStringList() {
return stringList;
}
public void setStringList(ArrayList<String> stringList) {
this.stringList = stringList;
}
public ArrayList<Integer> getIntegerList() {
return integerList;
}
public void setIntegerList(ArrayList<Integer> integerList) {
this.integerList = integerList;
}
}
---------------------------------------------------------------下面开始测试了------------------------------------------------------------------
测试类TestMain:
package tt;
import java.util.ArrayList;
import java.util.Arrays;
import tt.vo.Person;
public class TestMain {
public static void main(String[] args) throws CloneNotSupportedException {
// initialize Person p
Person p = new Person();
// String List
ArrayList<String> stringList = new ArrayList<String>();
stringList.addAll(Arrays.asList(new String("0"), new String("1")));
p.setStringList(stringList);
// Integer List
ArrayList<Integer> integerList = new ArrayList<Integer>();
integerList.addAll(Arrays.asList(new Integer("0"), new Integer("1")));
p.setIntegerList(integerList);
System.out.println("p:" + p);
Person pclone = p.clone();
System.out.println("pclone:" + pclone);
System.out.println("-------------after set-------------------");
// string list
String stringItem0 = p.getStringList().get(0);
stringItem0 = "0000";
p.getStringList().add("111111");
// integer list
Integer integerItem0 = p.getIntegerList().get(0) ;
integerItem0 = 999;
p.getIntegerList().add(88888);
System.out.println("p:" + p);
System.out.println("pclone:" + pclone);
}
}
debug截图:
通过debug可以发现:
- p.integerList = (ArrayList<Integer>) this.integerList.clone(); 是浅克隆, 在浅克隆之后:
- p.integerList(id=25)与 pclone.integerList(id=34) id不同
- 我们要知道ArrayList内部维护的是Object [] elementData。
- p.integerList.elementData(id=36)和pclone.integerList.elementData(id=47) id不同
- 说白了,还是数组的id不同(和我上一篇讲数组克隆情况一样),虽然数组里面的元素的id都相同,
- 但是在对p.integerList操作的时候(add,remove),是不会影响到pclone.integerList的
- 也因为是浅克隆:数组里面的元素的id都相同。
- 注意,这里要结合之前的帖子(Integer,String):
- 当从list取出Integer,String类型的变量之后,
- 你修改了stringItem0,integerItem0之后,是不会影响数组里面所对应的元素的。
- 至于原因?看看http://blog.csdn.net/miqi770/article/details/45223191
- 对于p.stringList和p.integerList的现象是一样的。