java中的clone()方法的研究---(10)如何编写正确的clone()方法:子自定义Object类型

在自定义类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 + "]";
	}
}



回到Person类


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得截图:



通过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的变化)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值