LuckyHu Blog

首页 产品 工作室

Java clone()方法,真不是我想的那么用.

07 Jan 2012

今天总算吃了一次没搞清楚某个方法的原理就乱用的亏。

情景:用某个对象数组的clone方法复制一个对象数组的副本进行处理(因为先看了api说是创建一个副本,就觉得应该是那样吧),程序很庞大,调试了半天,老出现一些奇怪的错误,百思不得其解,一直追踪下去,才开始怀疑是自己对这个colne方法的理解有错误(或者说api没说清楚…)。于是写了几个demo测试了下,才发现自己想得 too simple。

class TNumber {
	int num=0;
}

public static void main(String[] args) {
		TNumber[] n={new TNumber()};
		print(n[0].num);
		print(n);
		print(n[0]);

		TNumber[] anothern=n.clone();
		anothern[0].num=1;

		print(n[0].num);
		print(anothern);
		print(anothern[0]);
	}

public static  void  print(T t){
	System.out.println(t);
}

输出如下:

0 [Lcom.test.TNumber;@7c6768 com.test.TNumber@1690726 1 [Lcom.test.TNumber;@5483cd com.test.TNumber@1690726

从输出可见,自以为是在对副本进行操作,但改变了原数组中的值,通过打印显示对象数组的hash值确实不同,clone的时候是真创建了一个新的对象,而不是本身的引用,但对象数组其中的对象的hash值完全相同,那你操作数组肿的对象的时候就自然改变了原数组的值。

找了半天,才找到一篇比较靠谱的文章,介绍了java clone的东西。

今后要写自己不清楚的代码的时候,最好先写个demo测试下,不然会浪费更多时间。

另外在java中没有指针的概念,在操作一个对象的引用的时候一定要注意是否会改变原对象的值,如果会改变原对象的话,是否需要创建一个副本,如果需要,就要使用合适的方法来创建副本对象。