以前没怎么注意clone这个方法,今天特意测试了一下,就当做了解一下这个方法的根底吧。‘
首先是一个没什么具体意义的类,只是当做测试用。这个类实现了Cloneable 接口,虽然这是个接口但是这个接口中没有任何方法,只是一个标记接口,后面的Clone方法是复写自Object类的。
package com.cn.wxwinnie.java.clone;
/**
* @author 潇湘暮雨 E-mail:wxwinnie@hotmail.com
*
* @version 创建时间:2014年3月6日 下午4:35:45
*
*/
public class MyCloneableClass implements Cloneable {
private String field1;
private Integer field2;
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Integer getField2() {
return field2;
}
public void setField2(Integer field2) {
this.field2 = field2;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = null;
obj = (MyCloneableClass) super.clone();
return obj;
}
/**
* 为了方便测试,这里将toString重写一下,然后,HashCode还是保留作为判断是否是同一个对象的标准。
* 这里之所以可以用HashCode来判断是否是同一个对象的原因如下:
* 首先这个类直接继承自Object,这个类里面没有重写HashCode的方法,也就是这里调用的hashCode()实际上是Object类中的;
* 而Object类中的HashCode是一个native方法 ,其实际实现上是将对象在内存中的地址转化为一个整数。
* 在不特殊的情况下,一个地址也就表示一个对象吧。 JDK原文:This is typically
* implemented by converting the internal address of the object into an
* integer。
*/
@Override
public String toString() {
return "MyCloneableClass:{field1=" + field1 + ", field2=" + field2
+ "}" + "@" + Integer.toHexString(hashCode());
}
}
然后是测试了。
package com.cn.wxwinnie.java.clone;
/**
* @author 潇湘暮雨 E-mail:wxwinnie@hotmail.com
*
* @version 创建时间:2014年3月6日 下午4:36:43
*
*/
public class Test {
public static void main(String[] args) {
MyCloneableClass mcc1 = new MyCloneableClass();
mcc1.setField1("第一个字段");
mcc1.setField2(1234);
MyCloneableClass mcc2 = new MyCloneableClass();
//这么写了 实际上只创建了一个mcc对象。
mcc2 = mcc1;
System.out.println("改变前源对象:"+mcc1.toString());
System.out.println("改变前直接复制的来的对象:"+mcc2.toString());
mcc2.setField1("改变第一个字段");
System.out.println("改变后源对象:"+mcc1.toString());
System.out.println("改变后直接复制的来的对象:"+mcc2.toString());
try {
mcc2 = (MyCloneableClass)mcc1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println("clone的来的对象:"+mcc2.toString());
}
}
控制台结果为:
改变前源对象:MyCloneableClass:{field1=第一个字段, field2=1234}@67f1fba0
改变前直接复制的来的对象:MyCloneableClass:{field1=第一个字段, field2=1234}@67f1fba0
源对象:MyCloneableClass:{field1=改变第一个字段, field2=1234}@67f1fba0
直接复制的来的对象:MyCloneableClass:{field1=改变第一个字段, field2=1234}@67f1fba0
clone的来的对象:MyCloneableClass:{field1=改变第一个字段, field2=1234}@3fbefab0
从控制台的结果可以看出,虽然调用mcc2 = mcc1赋值,但是这两个对象还是同一个地址上的,也就是同一个对象。
而后面的clone出来的兑现就不是同一个地址上的了,但是clone出来的对象与源对象的属性值完全一样的。
以上就是在下的一些拙见,如有错误地方,欢迎大家纠正。