java.lang.Cloneable 实现深clone和浅clone

来源:互联网 发布:shake it动作数据 编辑:程序博客网 时间:2024/05/16 13:47

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.