Employee original = new Employee ("tomsui",4000);
Employee copy = original ;
original 与copy仅仅是åŒä¸€å¯¹è±¡çš„ä¸åŒå¼•用ã€?/p>
Â
æ–ÒŽ(gu¨©)³•åQˆäºŒåQ?‹¹…å…‹éš?/strong>
直接利用Objectçš„clone()æ–ÒŽ(gu¨©)³•åQ?/p>
protected Objectclone()Â Â throws CloneNotSupportedException
Employee copy = (Employee)original.clone();
注æ„两点åQ?/p>
1åQ?Objectçš„clone() 是protected. åªèƒ½åœ¨åŒ…内或å类调用.
2åQ?如果‹¹…克隆的对象ä¸å˜åœ¨å¯¹è±¡åÅžå¼çš„æˆå‘˜å˜é‡:
public class Employee
{
       String name;
       int salary;
       Date birthday;
}
那么:
 Employee copy = (Employee) original.clone();
åªæ˜¯æ‹¯‚´äº†original对象ä¸çš„基本¾cÕdž‹å’Œä¸å˜é‡.å¯å˜çš„对象æˆå‘˜å˜é‡æ‹·è´å¾—到的ä»ç„¶æ˜¯å¼•ç”?
ä¸å˜é‡åº”该包æ‹?å¯ä»¥å‚è§<java多线½E‹è®¾è®¡æ¨¡å¼?gt;Immutable模å¼ä¸ç•Œå®šçš„æƒ…况):
a. String¾cÕd¯¹è±?/p>
b. 被final定义,å对象在生å˜å‘¨æœŸä¸ä»…ä¿å˜ä¸€äº›å¸¸é‡?/p>
Â
æ–ÒŽ(gu¨©)³•(ä¸? 深克éš?/strong>
例å:
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;
               }
       }
}
 说明åQ?/p>
1åQ‰Employee 必须实现 CloneableæŽ¥å£ åQˆæ ‡å¿—接å£ï¼‰
Â Â Â Â Â æ ‡å¿—æŽ¥å£åQšå®Œå…¨çš„½IºæŽ¥å£ã€‚这里的作用是告诉JåQӞ݋åQŒç±»çš„设计者ç†è§£äº†cloneable()æ–ÒŽ(gu¨©)³•åQŒå¯ä»¥é€šè¿‡isInstanceOf˜q›è¡Œ˜q行时检查ã€?/p>
2åQ‰è¦†å†™çš„clone()æ–ÒŽ(gu¨©)³•必须定义为public (原是protected)
3åQ‰clone()æ–ÒŽ(gu¨©)³•体必™åÕdœ¨try-catch {}ä¸ï¼Œæ•获处ç†CloneNotSupportedException 。(防梾cÀL²¡æœ‰å®žçްCloneable接å£åQŒæ£¼‹®å®žçŽîCº†æ·±å…‹éš†çš„è¯ï¼Œ˜q™ä¸ªå¼‚常肯定ä¸ä¼š(x¨¬)抛出åQ?/p>
ï½ï½“.  JDKä¸ï¼ŒStringBuffer没有覆写clone()æ–ÒŽ(gu¨©)³•åQŒè™½ç„¶å®ƒ¼‹®å®ž¾l§æ‰¿äº†Objectçš„clone()åQŒä½†åœ¨å®žé™…应用ä¸åQŒã€€å› 䨓(f¨´)StringBuffer¾lä¸ä¼?x¨¬)有åç±»åQŒè€Œä¸”是在JDK外ä‹É用StringBufferåQŒæ‰€ä»¥è¢«protected界定的clone()æ–ÒŽ(gu¨©)³•是完全ä¸å¯è§çš„ï¼
Â
æ–ÒŽ(gu¨©)³•åQˆå››åQ‰ä‹É用åºåˆ—化˜q›è¡Œå…‹éš†
˜q™ç§æ–ÒŽ(gu¨©)³•涉åŠ(qi¨¢ng)IOæ“作åQŒæ‰€ä»¥ç›¸å¯ÒŽ(gu¨©)¥è®²è¦æ¯”方法(三)慢.
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;
}
Â
 æ–ÒŽ(gu¨©)³•åQˆäº”åQ?å…¶ä»–æ–ÒŽ(gu¨©)³•
å¯ä»¥é€šè¿‡java的垮„机制定义一个类ä¼égºŽå¯¹è±¡åºåˆ—化的万能克隆。改˜q›åŽå†è„“(chu¨¤ng)上æ¥ã€?/p>