相似的文章其實已經不少了,我只是記錄下本身的理解ide
經過Object.clone()
實現時須要注意如下2點,不然拋出CloneNotSupportedException
this
Cloneable
接口clone()
方法被拷貝對象實現Cloneable接口,而且重寫clone()方法便可code
class Kid { private String kname; public String getKname() { return kname; } public void setKname(String kname) { this.kname = kname; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((kname == null) ? 0 : kname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Kid other = (Kid) obj; if (kname == null) { if (other.kname != null) return false; } else if (!kname.equals(other.kname)) return false; return true; } } class BasicObj implements Cloneable { private String name; private Kid kid; public BasicObj(String name, Kid kid) { super(); this.name = name; this.kid = kid; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Kid getKid() { return kid; } public void setKid(Kid kid) { this.kid = kid; } } public class CopyTest { public static void main(String[] args) throws CloneNotSupportedException { Kid k = new Kid(); k.setKname("Apple"); BasicObj a = new BasicObj("Hello", k); BasicObj b = (BasicObj) a.clone(); System.out.println(a == b); System.out.println("a.id = " + a.getName() + ", b.id = " + b.getName()); System.out.println("a.kid.name = " + a.getKid().getKname() + ", b.kid.name = " + b.getKid().getKname()); System.out.println("a.kid.hashcode = " + a.getKid().hashCode() + ", b.kid.hashcode = " + b.getKid().hashCode()); System.out.println("---------------"); //改變了引用對象的值 k.setKname("Lemon"); a.setKid(k); //改變本地類型的值 a.setName("World"); System.out.println("a.id = " + a.getName() + ", b.id = " + b.getName()); System.out.println("a.kid.name = " + a.getKid().getKname() + ", b.kid.name = " + b.getKid().getKname()); System.out.println("a.kid.hashcode = " + a.getKid().hashCode() + ", b.kid.hashcode = " + b.getKid().hashCode()); } }
false a.id = Hello, b.id = Hello a.kid.name = Apple, b.kid.name = Apple a.kid.hashcode = 63476569, b.kid.hashcode = 63476569 --------------- a.id = World, b.id = Hello a.kid.name = Lemon, b.kid.name = Lemon a.kid.hashcode = 73304818, b.kid.hashcode = 73304818
被拷貝對象中的對引用類型須要實現Cloneable接口,且重寫clone()方法(相似遞歸操做,直至拷貝到基本類型爲止)對象
//引用類型對象實現了Cloneable接口 class Kid implements Cloneable { private String kname; public String getKname() { return kname; } public void setKname(String kname) { this.kname = kname; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((kname == null) ? 0 : kname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Kid other = (Kid) obj; if (kname == null) { if (other.kname != null) return false; } else if (!kname.equals(other.kname)) return false; return true; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class BasicObj implements Cloneable { private String name; private Kid kid; public BasicObj(String name, Kid kid) { super(); this.name = name; this.kid = kid; } //改造clone方法,對引用類型對象Kid進行clone操做 @Override protected Object clone() throws CloneNotSupportedException { BasicObj bo = new BasicObj(name, kid); bo.kid = (Kid) this.kid.clone(); return bo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Kid getKid() { return kid; } public void setKid(Kid kid) { this.kid = kid; } } public class CopyTest { public static void main(String[] args) throws CloneNotSupportedException { Kid k = new Kid(); k.setKname("Apple"); BasicObj a = new BasicObj("Hello", k); BasicObj b = (BasicObj) a.clone(); System.out.println(a == b); System.out.println("a.id = " + a.getName() + ", b.id = " + b.getName()); System.out.println("a.kid.name = " + a.getKid().getKname() + ", b.kid.name = " + b.getKid().getKname()); System.out.println("a.kid.hashcode = " + a.getKid().hashCode() + ", b.kid.hashcode = " + b.getKid().hashCode()); System.out.println("---------------"); //改變了引用對象的值 k.setKname("Lemon"); a.setKid(k); //改變本地類型的值 a.setName("World"); System.out.println("a.id = " + a.getName() + ", b.id = " + b.getName()); System.out.println("a.kid.name = " + a.getKid().getKname() + ", b.kid.name = " + b.getKid().getKname()); System.out.println("a.kid.hashcode = " + a.getKid().hashCode() + ", b.kid.hashcode = " + b.getKid().hashCode()); } }
false a.id = Hello, b.id = Hello a.kid.name = Apple, b.kid.name = Apple a.kid.hashcode = 63476569, b.kid.hashcode = 63476569 --------------- a.id = World, b.id = Hello a.kid.name = Lemon, b.kid.name = Apple a.kid.hashcode = 73304818, b.kid.hashcode = 63476569