在自定义类Person中,会有子自定义Object集合类型。
下面我就不一步步测试给大家看了,我就直接贴出来正确的clone方法了。
首先,我们有这样一个子对象类Hand,自己实现了clone方法。
package tt.vo;
public class Hand implements Cloneable {
private long size;
private Long length;
public Hand(long size, Long length) {
this.size = size;
this.length = length;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public Long getLength() {
return length;
}
public void setLength(Long length) {
this.length = length;
}
@Override
protected Hand clone() throws CloneNotSupportedException {
return (Hand) super.clone();
}
@Override
public String toString() {
return "Hand [size=" + size + ", length=" + length + "]";
}
}
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;
// String List
private ArrayList<String> stringList;
// Integer List
private ArrayList<Integer> integerList;
// 子自定义Object类型
private Hand hand;
@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 要强转类型
if (this.stringList != null) {
p.stringList = (ArrayList<String>) this.stringList.clone();
}
if (this.integerList != null) {
p.integerList = (ArrayList<Integer>) this.integerList.clone();
}
if (this.hand != null){ // 需要额外的,在调用子对象的clone方法
p.hand = this.hand.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 + ", hand=" + hand + "]";
}
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;
}
public Hand getHand() {
return hand;
}
public void setHand(Hand hand) {
this.hand = hand;
}
}
---------------------------------------------------------------下面开始测试了------------------------------------------------------------------
测试类TestMain:
package tt;
import tt.vo.Hand;
import tt.vo.Person;
public class TestMain {
public static void main(String[] args) throws CloneNotSupportedException {
// initialize Person p
Person p = new Person();
Hand hand = new Hand(5, 18l);
p.setHand(hand);
System.out.println("p:" + p);
Person pclone = p.clone();
System.out.println("pclone:" + pclone);
System.out.println("-------------after set-------------------");
Hand pHand = p.getHand();
pHand.setLength(1800l);
pHand.setSize(500);
System.out.println("p:" + p);
System.out.println("pclone:" + pclone);
}
}
通过debug可以发现:
- p.hand = this.hand.clone();是浅克隆
- 虽然p.hand(id=23),pclone.hand(id=26)的id不一样,但是你会发现,hand里面的德属性id 是一样的(p.hand.length(id=31),pclone.hand.length(id=31))
- 所以我说,是浅克隆!
Hand pHand = p.getHand();
pHand.setLength(1800l);
pHand.setSize(500);
之后。
- 你会发现,虽然是浅克隆,但是没有事,没有大碍!
- 原因是:http://blog.csdn.net/miqi770/article/details/45223191
- p.hand.length在修改之后,不会影响pclone.hand.length的,根本原因还是因为p.hand 和 pclone.hand 不是用一个对象(id不同)
运行完的,debug截图(注意id的变化)