淺拷貝和深拷貝概念:
淺拷貝和深拷貝都是針對一個已有對象的操作。那先來看看淺拷貝和深拷貝的概念。
在 Java 中,除了基本數據類型(元類型)之外,還存在 類的實例對象 這個引用數據類型。而一般使用 『 = 』號做賦值操作的時候。對於基本數據類型,實際上是拷貝的它的值,但是對於對象而言,其實賦值的只是這個對象的引用,將原對象的引用傳遞過去,他們實際上還是指向的同一個對象。
而淺拷貝和深拷貝就是在這個基礎之上做的區分,如果在拷貝這個對象的時候,只對基本數據類型進行了拷貝,而對引用數據類型只是進行了引用的傳遞,而沒有真實的創建一個新的對象,則認為是淺拷貝。反之,在對引用數據類型進行拷貝的時候,創建了一個新的對象,並且復制其內的成員變量,則認為是深拷貝。
所以到現在,就應該了解了,所謂的淺拷貝和深拷貝,只是在拷貝對象的時候,對 類的實例對象 這種引用數據類型的不同操作而已。
總結來說:
1、淺拷貝:對基本數據類型進行值傳遞,對引用數據類型進行引用傳遞般的拷貝,此為淺拷貝。
2、深拷貝:對基本數據類型進行值傳遞,對引用數據類型,創建一個新的對象,並復制其內容,此為深拷貝。
拷貝實現:
實現Cloneable接口,否則報java.lang.CloneNotSupportedException錯誤。
重寫Object中的clone()方法,並把該方法訪問修飾符改為public。
淺拷貝實現:
public class Book implements Cloneable{ private String name; private String[] authors; @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } //getter()、setter()。。。 }
import java.util.Arrays; public class Test { public static void main(String[] args) throws CloneNotSupportedException { Book book = new Book(); book.setName("Think in Java"); book.setAuthors(new String[]{"Alpha", "Mike"}); Book cloneBook = (Book) book.clone(); System.out.println("clone object[name="+cloneBook.getName()+"," + "authors="+ Arrays.toString(cloneBook.getAuthors())+"]"); System.out.println("引用對象是否是同一個:"+(book.getAuthors()==cloneBook.getAuthors())); } }
測試結果:
clone object[name=Think in Java,authors=[Alpha, Mike]] 引用對象是否是同一個:true
深拷貝實現:
public class Book implements Cloneable{ private String name; private String[] authors; @Override public Object clone() throws CloneNotSupportedException { Book cloneBook= (Book) super.clone(); //引用對象也拷貝一下 cloneBook.authors=this.authors.clone(); return cloneBook; } //getter()、setter()。。。 }
測試類:
import java.util.Arrays; public class Test { public static void main(String[] args) throws CloneNotSupportedException { Book book = new Book(); book.setName("Think in Java"); book.setAuthors(new String[]{"Alpha", "Mike"}); Book cloneBook = (Book) book.clone(); System.out.println("clone object[name="+cloneBook.getName()+"," + "authors="+ Arrays.toString(cloneBook.getAuthors())+"]"); System.out.println("引用對象是否是同一個:"+(book.getAuthors()==cloneBook.getAuthors())); } }
測試結果:
clone object[name=Think in Java,authors=[Alpha, Mike]] 引用對象是否是同一個:false