[JAVA]Object-物件的複製使用clone() 要使用clone(),需要實作介面Cloneable。 Object 類別本身不實作介面 Cloneable,所以在類別為 Object 的物件上調用 clone 方法將會導致在運行時拋出異常。 CloneNotSupportedException -  如果物件的類別不支持 Cloneable 介面,則覆寫 clone 方法的子類別也會拋出此異常,以指示無法複製某個實例。 Object 類別的 clone 方法執行特定的複製操作。 首先,如果此物件的類別不能實作介面 Cloneable, 則會拋出 CloneNotSupportedException。 注意,所有的陣列都被視為實作介面 Cloneable。 否則,此方法會創建此物件的類別的一個新實例,並像通過分派那樣, 嚴格使用此物件相應欄位的內容初始化該物件的所有欄位; 這些欄位的內容沒有被自我複製。 所以,此方法執行的是該物件的「淺表複製」,而不「深層複製」操作。 測試: 一般用法:(淺表複製)

package com.test;

public class TestClone implements Cloneable {
 public static final  int i=1;

 @Override
 public Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
 
 public static void main(String[] args) {
  
  try {
   TestClone t = new TestClone();
   //使用clone
   TestClone t1 = (TestClone) t.clone();
   //顯示記憶體位置
   System.out.println(t);
   //com.test.TestClone@150bd4d
   System.out.println(t1);
   //com.test.TestClone@1bc4459
   //位置是不一樣了,是不同的物件
   
   //陣列會自動implements Cloneable
   //所以會有clone的功能
   int i[] = {1,2,5,8,8,8};
   int a[]=i.clone();
   System.out.println(i.equals(a));
   //false
   System.out.println(a[2]);
   //5
  }
  catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
 }
}

進階用法:( 深層複製 ) 例: 用一般的用法:

package com.test;

import java.util.ArrayList;

public class TestCloneAdvanced implements Cloneable{

 private int   i;
 private ArrayList arrayList;

 @Override
 public String toString() {
  return "i=" + i + ",arrayList=" + arrayList;
 }

 public static void main(String[] args) {
  TestCloneAdvanced clone1 = new TestCloneAdvanced();
  clone1.i = 3;
  clone1.arrayList = new ArrayList();
  clone1.arrayList.add("value 1");
  TestCloneAdvanced clone2 = null;
  try {
   clone2 = (TestCloneAdvanced) clone1.clone();
  }
  catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  System.out.println("複製物件後,顯示結果:");
  System.out.println("clone1:" + clone1);
  System.out.println("clone2:" + clone2);
  System.out.println("將clone1改變值後,顯示結果:");
  clone1.i = 5;
  clone1.arrayList.add("value 2");
  System.out.println("clone1:" + clone1);
  System.out.println("clone2:" + clone2);
  System.out.println("將clone1改變值後,clone2的arrayList的值也會改");
  System.out.println("因為arrayList物件沒有複製");
  System.out.println("clone1.arrayList==clone2.arrayList?" +
                     (clone1.arrayList == clone2.arrayList));
 }

}
結果在物件裡的物件,無法複製。

結決方法:Override clone 例:

package com.test;

import java.util.ArrayList;

public class TestCloneAdvanced1 implements Cloneable {

 private int   i;
 private ArrayList arrayList;

 @Override
 public String toString() {
  return "i=" + i + ",arrayList=" + arrayList;
 }

 @Override
 public Object clone() throws CloneNotSupportedException {
  TestCloneAdvanced1 clone = (TestCloneAdvanced1) super.clone();
  clone.arrayList = (ArrayList) this.arrayList.clone();
  return clone;
 }

 public static void main(String[] args) {
  TestCloneAdvanced1 clone1 = new TestCloneAdvanced1();
  clone1.i = 3;
  clone1.arrayList = new ArrayList();
  clone1.arrayList.add("value 1");
  TestCloneAdvanced1 clone2 = null;
  try {
   clone2 = (TestCloneAdvanced1) clone1.clone();
  }
  catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  System.out.println("複製物件後,顯示結果:");
  System.out.println("clone1:" + clone1);
  System.out.println("clone2:" + clone2);
  System.out.println("將clone1改變值後,顯示結果:");
  clone1.i = 5;
  clone1.arrayList.add("value 2");
  System.out.println("clone1:" + clone1);
  System.out.println("clone2:" + clone2);
  System.out.println("將clone1改變值後,clone2的arrayList的值不會改了");
  System.out.println("clone1.arrayList==clone2.arrayList?" + 
                      (clone1.arrayList == clone2.arrayList));
 }

}

結果:

進階參考網站:

小妖與鴨居的家

 

 

其它文章

文章標籤
全站熱搜
創作者介紹
創作者 PG Levin Li 的頭像
PG Levin Li

程式開發學習之路

PG Levin Li 發表在 痞客邦 留言(0) 人氣(3,286)