http://tomsui.blog.hexun.com/4308236_d.html
          方法(一) 引用拷貝

          Employee original = new Employee ("tomsui",4000);

          Employee copy = original ;

          original 與copy僅僅是同一對象的不同引用。

          ?

          方法(二) 淺克隆

          直接利用Object的clone()方法:

          protected Objectclone()?? throws CloneNotSupportedException

          Employee copy = (Employee)original.clone();

          注意兩點:

          1) Object的clone() 是protected. 只能在包內或子類調用.

          2) 如果淺克隆的對象中存在對象形式的成員變量:

          public class Employee

          {

          ??????? String name;

          ??????? int salary;

          ??????? Date birthday;

          }

          那么:

          ? Employee copy = (Employee) original.clone();

          只是拷貝了original對象中的基本類型和不變量.可變的對象成員變量拷貝得到的仍然是引用.

          不變量應該包括(可以參見<java多線程設計模式>Immutable模式中界定的情況):

          a. String類對象

          b. 被final定義,子對象在生存周期中僅保存一些常量

          ?

          方法(三) 深克隆

          例子:

          class Employee implements Cloneable

          {

          ??????? private String name;

          ??????? private double salary;

          ??????? private Date birthday;

          ??????? // setter 與 getter

          ??????? public Object clone()

          ??????? {

          ??????????????? try

          ??????????????? {

          ??????????????????????? Employee cloned = (Employee ) super.clone();

          ??????????????????????? cloned.birthday = (Date) birthday.clone();

          ??????????????? }catch(CloneNotSupportedException e) {

          ??????????????? return null;

          ??????????????? }

          ??????? }

          }

          ?說明:

          1)Employee 必須實現 Cloneable接口 (標志接口)

          ?????標志接口:完全的空接口。這里的作用是告訴JVM,類的設計者理解了cloneable()方法,可以通過isInstanceOf進行運行時檢查。

          2)覆寫的clone()方法必須定義為public (原是protected)

          3)clone()方法體必須在try-catch {}中,捕獲處理CloneNotSupportedException 。(防止類沒有實現Cloneable接口,正確實現了深克隆的話,這個異常肯定不會拋出)

          ps.?? JDK中,StringBuffer沒有覆寫clone()方法,雖然它確實繼承了Object的clone(),但在實際應用中, 因為StringBuffer絕不會有子類,而且是在JDK外使用StringBuffer,所以被protected界定的clone()方法是完全不可見的!

          ?

          方法(四)使用序列化進行克隆

          這種方法涉及IO操作,所以相對來講要比方法(三)慢.

          import java.io.*;
          import java.util.*;

          public class SerialCloneTest
          {?
          ?? public static void main(String[] args)
          ?? {?
          ????? Employee harry = new Employee("Harry Hacker", 35000,
          ???????? 1989, 10, 1);
          ????? // clone harry
          ????? Employee harry2 = (Employee)harry.clone();

          ????? // mutate harry
          ????? harry.raiseSalary(10);

          ????? // now harry and the clone are different
          ????? System.out.println(harry);
          ????? System.out.println(harry2);
          ?? }
          }

          /**
          ?? A class whose clone method uses serialization.
          */
          class SerialCloneable implements Cloneable, Serializable
          {?
          ?? public Object clone()
          ?? {?
          ????? try
          ????? {?
          ???????? // save the object to a byte array
          ???????? ByteArrayOutputStream bout = new
          ??????????? ByteArrayOutputStream();
          ???????? ObjectOutputStream out
          ??????????? = new ObjectOutputStream(bout);
          ???????? out.writeObject(this);
          ???????? out.close();

          ???????? // read a clone of the object from the byte array
          ???????? ByteArrayInputStream bin = new
          ??????????? ByteArrayInputStream(bout.toByteArray());
          ???????? ObjectInputStream in = new ObjectInputStream(bin);
          ???????? Object ret = in.readObject();
          ???????? in.close();

          ???????? return ret;
          ????? }?
          ????? catch (Exception e)
          ????? {?
          ???????? return null;
          ????? }
          ?? }
          }

          /**
          ?? The familiar Employee class, redefined to extend the
          ?? SerialCloneable class.
          */
          class Employee extends SerialCloneable
          {?
          ?? public Employee(String n, double s,
          ????? int year, int month, int day)
          ?? {?
          ????? name = n;
          ????? salary = s;
          ????? GregorianCalendar calendar
          ???????? = new GregorianCalendar(year, month - 1, day);
          ???????? // GregorianCalendar uses 0 for January
          ????? hireDay = calendar.getTime();
          ?? }

          ?? public String getName()
          ?? {?
          ????? return name;
          ?? }

          ?? public double getSalary()
          ?? {?
          ????? return salary;
          ?? }

          ?? public Date getHireDay()
          ?? {?
          ????? return hireDay;
          ?? }

          ?? public void raiseSalary(double byPercent)
          ?? {?
          ????? double raise = salary * byPercent / 100;
          ????? salary += raise;
          ?? }

          ?? public String toString()
          ?? {?
          ????? return getClass().getName()
          ???????? + "[name=" + name
          ???????? + ",salary=" + salary
          ???????? + ",hireDay=" + hireDay
          ???????? + "]";
          ?? }

          ?? private String name;
          ?? private double salary;
          ?? private Date hireDay;
          }

          ?

          ?方法(五) 其他方法

          可以通過java的反射機制定義一個類似于對象序列化的萬能克隆。改進后再貼上來。

          posted on 2006-08-29 15:04 pear 閱讀(1033) 評論(0)  編輯  收藏 所屬分類: 技術
           
          主站蜘蛛池模板: 广宗县| 株洲县| 安吉县| 定安县| 武冈市| 眉山市| 玛纳斯县| 项城市| 德清县| 阿荣旗| 满城县| 皮山县| 莒南县| 怀远县| 哈密市| 成都市| 深泽县| 衡南县| 临潭县| 镇坪县| 平乡县| 海阳市| 巫山县| 定州市| 乌兰浩特市| 丰镇市| 兖州市| 平塘县| 皋兰县| 高雄市| 保定市| 冀州市| 无锡市| 钟祥市| 扶沟县| 乐亭县| 河源市| 襄樊市| 焉耆| 鄯善县| 丁青县|