例子:
- class Person implements Cloneable {
- private String name;
- private int age;
- 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;
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + "]";
- }
- }
- Person p1 = new Person();
- p1.setName("zhangsan");
- p1.setAge(20);
- Person p2 = (Person) p1.clone();
- p2.setName("lisi");
- System.out.println(p1);
- System.out.println(p2);
首先我們看看淺拷貝和深拷貝的定義
淺拷貝:只複製一個對象,對象內部存在的指向其他對象數組或者引用則不復制
深拷貝:對象,對象內部的引用均複製
爲了更好的理解它們的區別我們假設有一個對象A,它包含有2對象對象A1和對象A2
對象A進行淺拷貝後,得到對象B但是對象A1和A2並沒有被拷貝
對象A進行深拷貝,得到對象B的同時A1和A2連同它們的引用也被拷貝
在理解了深拷貝和淺拷貝後,我們來看看Java的深拷貝和淺拷貝實現。java.lang.Object的clone()方法默認是返回一個淺拷貝對象。因此如果要用clone()方法實現一個深拷貝,我們必須對每個對象的clone()方法進行特別實現。當對象層次複雜的時候,這樣做不但困難而且浪費時間和容易出現錯誤,特別有時候你不但需要深拷貝同時你也對這個對象進行淺拷貝的時候,你會發現寫這個clone()方法真不是一個好的解決方案。
那麼除了clone()方法,我們還可以怎麼實現呢?答案是序列化,實現步驟和思路是把要拷貝的對象輸出成byte array,然後再利用ObjectInputStream轉換出新的對象。下面是代碼
- public static Object copy(Object oldObj) {
- Object obj = null;
- try {
- // Write the object out to a byte array
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(bos);
- out.writeObject(oldObj);
- out.flush();
- out.close();
- // Retrieve an input stream from the byte array and read
- // a copy of the object back in.
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bis);
- obj = in.readObject();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException cnfe) {
- cnfe.printStackTrace();
- }
- return obj;
- }