obj.clone().getClass()==obj.getClass(),即它们具有相同的类型。还有一点,因为只是简单的将对象的空间进行复 制,所以如果类具有引用类型的实例变量的话,也只是将这个引用进行拷贝,并不复制其引用的对象。这就导致拷贝对象的引用实例变量与原对象的指向相同的对 象,这就是传说中的“浅拷贝”。如果实例变量引用的对象是不可变的,类似于String,则拷贝对象与原对象不能互相影响,这样的拷贝是成功的。但是如果 引用的是可变对象,它们就会影响彼此,对于成功的拷贝而言,这是不允许的。可以对可变的实例变量对象进行特殊处理,以实现拷贝对象和原对象不能相互影响的 “深拷贝”。
由于Object.clone()方法是protected的,所以它只能在lang包中的类或是其子类的方法内部被调用,所以,如果像下面这样调用,会 编译出错,在Person kobe_bak=kobe.clone();报错,说clone只能在Object的protected作用域访问。
一个类可以被clone,必须满足两点:
第一,它必须实现了Cloneable接口,否则会抛出CloneNotSupportedException异常。第二,它必须提供一个public的clone方法,也就是重写Object.clone()方法,否则编译不能通过。第三,对于存在可变域的类,在clone方法中需要对这些可变域进行拷贝。package test.javacopy;import java.util.Date;/** * Created by Administrator on 2016/1/5. */public class JavaCopy implements Cloneable { private String name; private int age; private Date date; private TestCopy testcopy; public JavaCopy(String name,int age){ this.name = name; this.age = age; } public JavaCopy clone(){ JavaCopy javaCopy = null; try { javaCopy = (JavaCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return javaCopy; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public TestCopy getTestcopy() { return testcopy; } public void setTestcopy(TestCopy testcopy) { this.testcopy = testcopy; }}
package test.javacopy;import java.io.Serializable;import java.util.Date;/** * Created by Administrator on 2016/1/5. */public class TestCopy implements Serializable,Cloneable{ private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public TestCopy clone(){ TestCopy testCopy = null; try { testCopy = (TestCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return testCopy; } public static void main(String args[]) { TestCopy testcopy = new TestCopy(); testcopy.setName("javaCopy"); JavaCopy javaCopy = new JavaCopy("123", 123); javaCopy.setDate(new Date()); javaCopy.setTestcopy(testcopy); JavaCopy javaCopy1 = javaCopy.clone(); System.out.println("===javaCopy1===" + javaCopy1.getName() + "age" + javaCopy1.getAge() + "date" + javaCopy1.getDate()); javaCopy1.setName("321"); javaCopy1.setAge(321); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } javaCopy.setDate(new Date()); javaCopy.getTestcopy().setName("javaCopy1"); System.out.println("===javaCopy=== name" + javaCopy.getName()); System.out.println("===javaCopy1=== name" + javaCopy1.getName()); System.out.println("===javaCopy=== age" + javaCopy.getAge()); System.out.println("===javaCopy1=== age" + javaCopy1.getAge()); System.out.println("===javaCopy=== date" + javaCopy.getDate()); System.out.println("===javaCopy1=== date" + javaCopy1.getDate()); System.out.println("===javaCopy=== testcopy name" + javaCopy.getTestcopy().getName()); System.out.println("===javaCopy1=== testcopy name" + javaCopy1.getTestcopy().getName()); }}
执行的结果:
===javaCopy1===123age123dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== name123===javaCopy1=== name321===javaCopy=== age123===javaCopy1=== age321===javaCopy=== dateTue Jan 05 13:52:11 GMT+08:00 2016===javaCopy1=== dateTue Jan 05 13:52:09 GMT+08:00 2016===javaCopy=== testcopy namejavaCopy1===javaCopy1=== testcopy namejavaCopy1注意添加的粗字体的代码(深拷贝)
public JavaCopy clone(){ JavaCopy javaCopy = null; try { javaCopy = (JavaCopy)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return javaCopy; }
执行结果:
===javaCopy=== dateTue Jan 05 13:55:15 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:55:13 GMT+08:00 2016===javaCopy=== testcopy namejavaCopy1===javaCopy1=== testcopy namejavaCopyjdk中的arraylist深拷贝实现:
public Object clone() {try { ArrayListv = (ArrayList ) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v;} catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError();} }