java中的Cloneable和Serializable接口,實現淺克隆和深度克隆

 java.lang.Cloneable 接口是一個空接口,該接口用來指明一個對象是否可以進行克隆.實現了該接口的對象可以調用clone()方法來進行對象的淺克隆.

/*
 * @author 黎龍飛 , 創建日期 2008-4-16
 *
 * Blog : http://lilongfei1030.blog.163.com
 */
package com.lang.test;

import java.util.Vector;

class Example implements Cloneable {

 private Vector<String> vector = new Vector<String>();

 private String name;

 public void setName(String name) {
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void add(String s) {
  vector.add(s);
 }

 public int getSize() {
  return vector.size();
 }

 @SuppressWarnings("finally")
 public Object clone() {
  Example temp = null;
  try {
   temp = (Example) super.clone();
   // return temp;
  } catch (CloneNotSupportedException e) {
   System.out.println("Clone failed");
  } finally {
   return temp;
  }
 }
}

public class TestSample {
 public TestSample() {

 }

 public static void main(String[] args) {
  Example oldExample = new Example();
  oldExample.setName("old");
  oldExample.add("old");
  Example newExample = (Example) oldExample.clone();
  newExample.setName("new");
  newExample.add("new");
  System.out.println("oldExample's name is:" + oldExample.getName());
  System.out.println("newExample's name is:" + newExample.getName());
  System.out.println("oldExample's size is:" + oldExample.getSize());
  System.out.println("newExample's size is:" + newExample.getSize());

 }

}
/**

oldExample's name is:old
newExample's name is:new
oldExample's size is:2
newExample's size is:2

*/

       java默認的克隆是淺克隆,淺克隆僅僅克隆所考慮的對象,而不克隆它所引用的對象.所以對於oldExample和newException,其所引用的Vector對象爲一個;

下面是一個使用深克隆的類:

* @author 黎龍飛 , 創建日期 2008-4-16
 *
 * Blog : http://lilongfei1030.blog.163.com
 */
package com.lang.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Vector;

class DeepClone implements Cloneable, Serializable {

 private static final long serialVersionUID = -7118913611910178839L;

 private Vector<String> vector = new Vector<String>();

 private String name;

 public void setName(String name) {
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void add(String s) {
  vector.add(s);
 }

 public int getSize() {
  return vector.size();
 }

 public Object clone() {
  try {
   ByteArrayOutputStream b = new ByteArrayOutputStream();
   ObjectOutputStream out = new ObjectOutputStream(b);
   out.writeObject(this); //writeObject 方法用於將對象寫入流中。必須使用與寫入對象時相同的類型和順序從相應 ObjectInputstream 中讀回對象。 
   ByteArrayInputStream bIn = new ByteArrayInputStream(b.toByteArray());
   ObjectInputStream oi = new ObjectInputStream(bIn);
   return (oi.readObject());
  } catch (Exception e) {
   return null;
  }
 }
}

public class TestDeepClone {
 public static void main(String[] args) {
  DeepClone oldExample = new DeepClone();
  oldExample.setName("old");
  oldExample.add("old");
  DeepClone newExample = (DeepClone) oldExample.clone();
  newExample.setName("new");
  newExample.add("new");
  System.out.println("oldExample's name is:" + oldExample.getName());
  System.out.println("oldExample's size is:" + oldExample.getSize());
  System.out.println("newExample's name is:" + newExample.getName());
  System.out.println("newExample's size is:" + newExample.getSize());
 }

}
/*

oldExample's name is:old
oldExample's size is:1
newExample's name is:new
newExample's size is:2

*/
    在這種實現中,通過對象序列化方式,深克隆把要複製對象都複製了一遍.其中關於ObjectOutputStream 與ObjectInputStream 的使用可參考Java API

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章