java中的clone()方法的研究---(8)如何编写正确的clone()方法:数组类型

在自定义类Person中,会有String, Integer 类型。我们总结的是,针对这些类型的字段,在clone()方法里面,不需要有特别的处理。

但是!!!!!!!

String, Integer类型的数组,在clone()方法里面,是需要特别处理的!!!!


下面来看看我的测试流程。

先在自定义类Person中,添加 String [] , int [] 和 Integer [] 两个属性。


package tt.vo;

import java.sql.Timestamp;
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;

	@Override
	public Person clone() throws CloneNotSupportedException {
		Person p = (Person) super.clone();

		// StringBuffer,StringBuilder 没有实现clone方法
		// 只能用 new, 去完成克隆动作
		p.address1 = new StringBuffer(this.address1);
		p.address2 = new StringBuilder(this.address2);

		p.date = (Date) this.date.clone();
		p.timestamp = (Timestamp) this.timestamp.clone();

		// 这里我先给注释掉
		// p.intArray = this.intArray.clone();
		// p.integerArray = this.integerArray.clone();
		// p.stringArray = this.stringArray.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) + "]";
	}

	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;
	}

}



---------------------------------------------------------------下面开始测试了------------------------------------------------------------------

测试类TestMain:


package tt;

import java.sql.Timestamp;
import java.util.Date;

import tt.vo.Person;

public class TestMain {

	public static void main(String[] args) throws CloneNotSupportedException {
		// initialize Person p
		Person p = new Person();
		
		// int 
		p.setAge(18);
		
		// Integer
		p.setHeight(162);
		
		// String
		p.setName("郭美美");
		
		// StringBuffer
		p.setAddress1(new StringBuffer("中国北京"));
		
		// StringBuilder
		p.setAddress2(new StringBuilder("美国纽约"));
		
		// Date
		p.setDate(new Date());
		
		// Timestamp
		p.setTimestamp(new Timestamp(123456789l));
		
		// int array
		p.setIntArray(new int [] {10,11,12,13});
		
		// Integer array
		p.setIntegerArray(new Integer [] {1,2,3,4});
		
		// String array
		p.setStringArray(new String [] {"a","b","c","d"});
		
		System.out.println("p:" + p);
		Person pclone = p.clone();
		System.out.println("pclone:" + pclone);
		
		
		
		
		System.out.println("-------------after set-------------------");
		
		p.setAge(180);	
		p.setHeight(190);
		p.setName("郭美美不美");
		pclone.getAddress1().append("!!!");
		pclone.getAddress2().append("......");
		
		p.getDate().setYear(2000);
		p.getTimestamp().setYear(3000);

		p.getIntArray()[3] = 1000;
		p.getIntegerArray()[3] = 4000;
		p.getStringArray()[3] = "dddd";
		
		
		System.out.println("p:" + p);
		System.out.println("pclone:" + pclone);
	}

	
	
}



debug截图:




通过debug可以发现:p.intArray, p.integerArray p.stringArray 和 克隆出来的pclone.intArray, pclone.integerArray  pclone.stringArray的id完全相同。包括数组本身的id(36 39 43)和数组元素的id

当如下代码被执行之后,我们再来看看debug的截图

p.getIntArray()[3] = 1000;
p.getIntegerArray()[3] = 4000;
p.getStringArray()[3] = "dddd";




通过debug可以发现:

  • 对p.getIntegerArray()[3] 的修改,同时也影响了 pclone.getIntegerArray()[3]
  • 在修改p.getIntegerArray()[3]之后,  p.getIntegerArray()[3]  和 pclone.getIntegerArray()[3] 同时指向了一个新的内存地址 (id=383)
  • p.getStringArray()[3] 也是一样
  • p.getIntArray()[3] 因为是int 数组,所以数组元素没有id。但是效果是一样的,对p.getIntArray()[3]的修改,同时也修改了pclone.getIntArray()[3]
  • 好吧,这显然不是我们想要的结果。


解决办法如下,修改clone()方法

	@Override
	public Person clone() throws CloneNotSupportedException {
		Person p = (Person) super.clone();

		// StringBuffer,StringBuilder 没有实现clone方法
		// 只能用 new, 去完成克隆动作
		p.address1 = new StringBuffer(this.address1);
		p.address2 = new StringBuilder(this.address2);

		p.date = (Date) this.date.clone();
		p.timestamp = (Timestamp) this.timestamp.clone();

		p.intArray = this.intArray.clone();
		p.integerArray = this.integerArray.clone();
		p.stringArray = this.stringArray.clone();

		return p;
	}




哈哈,你会发现无论什么类型的数组,其实都自带clone()方法。不知道为什么String类型没有clone()望大师们赐教!!! 害羞

修改了clone()方法之后,我们再debug看看:





通过debug可以发现:

  • 从id上看p.integerArray(id=50) ,pclone.integerArray(id=39) 本身的id 不同 
  • 但是其数组元素的id都是相同的!!!!!!!!!!!!!!!!!!!!
  • p.stringArray 与 pclone.stringArray之间,   p.intArray 与pclone.intArray之间, 也是相同的现象。
  • 那么这样id小小的不同点,会有如何质的变化呢?我们接着来看


测试方法还是一样:

p.getIntArray()[3] = 1000;		
p.getIntegerArray()[3] = 4000;
p.getStringArray()[3] = "dddd";


来看看debug 截图:


通过debug可以发现:
  • 在修改p.getIntegerArray()[3]之后,  只是p.getIntegerArray()[3]  指向了一个新的内存地址 (id=172)。pclone.getIntegerArray()[3]不变
  • 修改了p.getStringArray()[3] 和p.getIntArray()[3]  的现象也是一样
  • 好吧,这就是我们想要的结果。

来看看控制台:

-------------after set-------------------
p:Person [integerArray=[1, 2, 3, 4000], stringArray=[a, b, c, dddd]]
pclone:Person [integerArray=[1, 2, 3, 4], stringArray=[a, b, c, d]]



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值