相似的文章其实已经不少了,我只是记录下本身的理解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