1. 程式人生 > >Java中克隆(Clone)一個對象

Java中克隆(Clone)一個對象

cloneabl puts 返回 print ack pcl 序列化 trac write

在開發過程中,可能會遇到我們需要一個和某個對象一樣數據,但是不是同一個內存地址的新對象,這個時候就需要用到Clone()了.

不過.註意,Clone()分為淺拷貝和深拷貝.區別在於要拷貝的對象是否有非基本變量.

1.如果一個對象是這樣的:

 1 public class CloneMan {
 2     /** 
 3      * @fields id 克隆人id
 4      */ 
 5     private int id;
 6     /** 
 7      * @fields isM 克隆人性別
 8      */ 
 9     private boolean isM;
10     
11
public CloneMan(int id, boolean isM) { 12 this.id = id; 13 this.isM = isM; 14 } 15 16 public int getId() { 17 return id; 18 } 19 public void setId(int id) { 20 this.id = id; 21 } 22 public boolean isM() { 23 return isM; 24 }
25 public void setM(boolean isM) { 26 this.isM = isM; 27 } 28 }

CloneMan類只有基本變量類型的成員變量,那麽Clone一個,只需要實現Cloneable接口,重寫Clone()方法即可

 1 public class CloneMan implements Cloneable{
 2     /** 
 3      * @fields id 克隆人id
 4      */ 
 5     private int id;
 6     /** 
 7      * @fields isM 克隆人性別
8 */ 9 private boolean isM; 10 11 public CloneMan(int id, boolean isM) { 12 this.id = id; 13 this.isM = isM; 14 } 15 16 public int getId() { 17 return id; 18 } 19 public void setId(int id) { 20 this.id = id; 21 } 22 public boolean isM() { 23 return isM; 24 } 25 public void setM(boolean isM) { 26 this.isM = isM; 27 } 28 29 public CloneMan clone() { 30 try { 31 return (CloneMan)super.clone(); 32 } catch (CloneNotSupportedException e) { 33 e.printStackTrace(); 34 return null; 35 } 36 } 37 }

通過clone()方法就可以獲取到新的CloneMan對象.

但是,如果需要克隆的類的成員變量包括了非基本類型的,如String,那麽這種方法就失效了.因為裏面的非基本變量類型也需要重寫clone()方法,這種方式我覺得太麻煩了.

通過查找資料,我知道一個通過IO流來clone對象的方法,親測有效

public static Object deepClone(Object obj) {
        //將對象寫入流中
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            //將對象從流中讀出來
            ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
            ObjectInputStream oi = new ObjectInputStream(bi);
            return oi.readObject();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

###註意:這裏傳入的Object要實現可序列化接口Serializable###

這裏得到的是一個Object對象,可以在獲取後進行強轉獲取到想要的類型,我這裏處理的是如果有異常返回的是null,所以獲取後要進行一次非空判斷.

因為這個是一個通用方法,可以卸載IOUtil中公用

Java中克隆(Clone)一個對象