AntSoul

它总是在行走,行走,永远的行走…… 行走是它生存的恒久姿态和最佳造型。 它似乎有一双不知疲倦的脚。 ———我说的是蚂蚁。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  42 随笔 :: 0 文章 :: 1 评论 :: 0 Trackbacks

   有的时候我们为了获取对象的一份copy,可以利用Object类的clone方法来实现,要想实现克隆,我们必须在派生类中实现Cloneable interface并覆盖基类的clone()方法,并扩大访问权限为public,在派生类的clone()方法,调用super.clone()。

 demo:
class StringTest
{
 public static void main(String[] args)
 {
  Professior p = new Professior("wangwu",50);
  Student s1 = new Student("zhangsan",18,p);
  Student s2 = (Student)s1.clone();
  s2.p.name = "lisi";
  s2.p.age = 20;
  
  System.out.println("s1.p.name="+s1.p.name+","+"s1.p.age="+s1.p.age);
 }
}

class Student implements Cloneable
{
  Professior p;
  String name;
  int age;
 
 public Student(String name,int age,Professior p)
 {
  this.name =name;
  this.age = age;
  this.p = p;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o=super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  return o;
 }
 
 public String toString()
 {
  return "name="+name+","+"age="+age;
 }
}

class Professior
{
 String name;
 int age;
 public Professior(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
}

Result:
D:\jcode>java StringTest
s1.p.name=lisi,s1.p.age=20
通过结果看得出一个问题,当我们修改s2的Professior后,s1对象的Professior对象的值被修改了。不是有clone了2份copy吗?那怎么修改S1的值却影响了S2的值了,那是因为我们克隆的时候只是把Professior的引用复制了一份,而并没有实际在内存中给它分配到一块内存,所以我们clone的时候,其实是把同一个值给复制了2次,所以s1和s2操作的professior都是同一个对象,所以修改S1,必然就影响了S2的professior的值,那我们的本意并非如此,有没有办法解决呢?答案是肯定的。其实我们刚才所做的操作是一个浅克隆,当我们克隆的对象是引用类型的时候,可以用深克隆来实现。就如下面的Demo.
class CloneTest
{
 public static void main(String[] args)
 {
  Boss boss = new Boss("antsoul",25);
  Leader leader = new Leader("linda",30);
  Employee ep1 = new Employee("zhangsan",107,leader,boss);
    Employee ep2 = (Employee)ep1.clone();
    ep2.boss.name = "gll";
    ep2.boss.age = 60;
    System.out.println("ep1.leader.name="+ep1.boss.name);
    System.out.println("ep1.leader.age="+ep1.boss.age);
 } 
}

class Employee implements Cloneable
{
 String name;
 int eid;
 Leader leader;
 Boss boss;
 
 Employee(String name,int eid,Leader leader,Boss boss)
 {
  this.name = name;
  this.eid = eid;
  this.leader = leader;
  this.boss = boss;
 }
 
 public Object clone()
 {
  Employee o = null;
  try
  {
   o = (Employee)super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  o.leader = (Leader)leader.clone();
  o.boss = (Boss)boss.clone();
  return o;
 }
}

class Leader implements Cloneable
{
 String name;
 int age;
 
 Leader(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o = super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.toString());
  }
  return o;
 }
}

class Boss implements Cloneable
{
 String name;
 int age;
 
 Boss(String name,int age)
 {
  this.name = name;
  this.age = age;
 }
 
 public Object clone()
 {
  Object o = null;
  try
  {
   o = super.clone();
  }
  catch(CloneNotSupportedException e)
  {
   System.out.println(e.getMessage());
  }
  return o;
 }
}

这里有个疑问了,为什么我们要在派生类中over writte Object的clone()方法时,一定要调用super.clone()呢?
原因是: 在运行时刻,Object中的clone()识别出你要clone的是哪一个对象,然后为此对象分配内存空间,并进行对象的复制,将原始对象的内容一一复制到新的对象空间中去。

posted on 2007-03-12 15:30 yok 阅读(169) 评论(0)  编辑  收藏 所属分类: CoreJava

只有注册用户登录后才能发表评论。


网站导航: