Object中clone()方法是protected的,是淺拷貝,要使用clone方法,要重寫它,只有實現了implements Cloneable才可以調用該方法,否則會拋出CloneNotSupportedException異常。
@Override public Object clone(){ Object o = null; try { o = super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } // Person p = (Person) o; // p.book = (Book)p.getBook().clone(); //放開這兩段即為深拷貝的用法 return o; }
在我們需要復制對象的時候常用的三種方式
public static void main(String[] args){
Book b = new Book("java");
Person p = new Person("wt",b);
Person p1 = new Person(p);
Person p2 = (Person) p.clone();
b.setBookName("js");
p.setName("zjj");
System.out.println("P:"+p);
System.out.println("P1:"+p1);
System.out.println("P2:"+p2);
}
當clone使用淺拷貝(即不放開那兩段)時,只拷貝對象不包含對對象引用的對象的拷貝:
P:{name:zjj, book:{bookName:js}} P1:{name:wt, book:{bookName:js}} //不論是p1還是p2,基本類型的數值是直接拷貝值的,但是引用類型的對象卻是拷貝地址的 P2:{name:wt, book:{bookName:js}} //這樣一旦p的原始值引用的對象改變,淺拷貝后的對象也會隨之變化
當clone使用深拷貝(即放開那兩段)時:
P2:{name:wt, book:{bookName:java}} //深拷貝時,連對象中的對象都進行的是值拷貝,所以原始值的引用對象改變不會影響它
完整源代碼:
person類
public class Person implements Cloneable { private String name; private Book book; public Person(String name, Book book) { this.name = name; this.book = book; } public Person(Person p) { this.name = p.name; this.book = p.book; } @Override public Object clone(){ Object o = null; try { o = super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } Person p = (Person) o; p.book = (Book)p.getBook().clone(); return o; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } @Override public String toString() { return "{name:" + name + ", book:" + book + "}"; } }
book類
public class Book implements Cloneable{ private String bookName; public Book(String bookName) { this.bookName = bookName; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } @Override public String toString() { return "{bookName:" + bookName + "}"; } @Override public Object clone(){ Object o = null; try { o = super.clone(); }catch (CloneNotSupportedException e){ e.printStackTrace(); } return o; } }
clone測試類
public class CloneTest { public static void main(String[] args){ Book b = new Book("java"); Person p = new Person("wt",b); Person p1 = new Person(p); Person p2 = (Person) p.clone(); b.setBookName("js"); p.setName("zjj"); System.out.println("P:"+p); System.out.println("P1:"+p1); System.out.println("P2:"+p2); } }
