1.Java里的clone分为两种形式:
       A:浅克隆: 浅克隆仅仅克隆所考虑的对象,而不复制它所引用的对象。
       b:深克隆:深克隆不仅克隆所考虑的对象,还要克隆其引用所有对象。
Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。必须要遵循下面三点
1、在派生类中实现Cloneable接口。
2、.在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
3、.在派生类的clone()方法中,调用super.clone()。

现在举例说明:

浅克隆:Java中的Object类里的clone是浅克隆。

一个教师类如下:


public 
    
  class 
   Teacher {
     
  public 
    
  int 
   age;
     
  public 
   String name;

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   String getName() {
         
  return 
   name;
    }

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

}


一个学生类如下(如果应用Object类中的clone实现克隆功能就要实现Cloneable接口):

 


public 
    
  class 
   Student  
  implements 
   Cloneable{
     
  public 
   String name;
     
  public 
    
  int 
   age;
     
  public 
   Teacher teacher;

     
  public 
   String getName() {
         
  return 
   name;
    }

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

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   Teacher getTeacher() {
         
  return 
   teacher;
    }

     
  public 
    
  void 
   setTeacher(Teacher teacher) {
         
  this 
  .teacher  
  = 
   teacher;
    }
    @Override
     
  protected 
   Object clone()  
  throws 
   CloneNotSupportedException {
         
  return 
    
  super 
  .clone();
    }


测试浅克隆如下:

 


public 
    
  class 
   TestClone {
     
  public 
    
  static 
    
  void 
   main(String[] args) {
        Teacher teacher  
  = 
    
  new 
   Teacher();
        teacher.setAge( 
  21 
  );
        teacher.setName( 
  " 
  Teacher Zhang 
  " 
  );

        Student student1  
  = 
    
  new 
   Student();
        student1.setAge( 
  5 
  );
        student1.setName( 
  " 
  Student zhangsan 
  " 
  );
        student1.setTeacher(teacher);

         
  // 
   复制出来一个对象student2 
  
 
          Student student2;
         
  try 
   {
            student2  
  = 
   (Student) student1.clone();
            System.out.println(student2.getAge());
            System.out.println(student2.getName());

            System.out.println( 
  " 
  ~~~~~~~~~~~~~~~~~~~~~~ 
  " 
  );
            System.out.println(student1.getTeacher().getAge());
            System.out.println(student1.getTeacher().getName());

             
  // 
   修改student2的引用对象 
  
 
              student2.getTeacher().setAge( 
  50 
  );
            student2.getTeacher().setName( 
  " 
  Teacher Li 
  " 
  );

            System.out.println( 
  " 
  ~~~~~~~~~~~~~~~~~~~~~~ 
  " 
  );
            System.out.println(student1.getTeacher().getAge());
            System.out.println(student1.getTeacher().getName());

        }  
  catch 
   (CloneNotSupportedException e) {
             
  // 
   TODO Auto-generated catch block 
  
 
              e.printStackTrace();
        }

    }
}


执行结果如下:

5
Student zhangsan
~~~~~~~~~~~~~~~~~~~~~~
21
Teacher Zhang
~~~~~~~~~~~~~~~~~~~~~~
50
Teacher Li

深克隆(一):

教师类如下:(如果应用Object类中的clone实现克隆功能就要实现Cloneable接口

 


public 
    
  class 
   Teacher  
  implements 
   Cloneable{
     
  public 
    
  int 
   age;
     
  public 
   String name;

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   String getName() {
         
  return 
   name;
    }

     
  public 
    
  void 
   setName(String name) {
         
  this 
  .name  
  = 
   name;
    }
    @Override
     
  protected 
   Object clone()  
  throws 
   CloneNotSupportedException {
         
  return 
    
  super 
  .clone();
    }
}


学生类如下:(要实现深克隆就要把其引用的对象全部克隆)

 


public 
    
  class 
   Student  
  implements 
   Cloneable{
     
  public 
   String name;
     
  public 
    
  int 
   age;
     
  public 
   Teacher teacher;

     
  public 
   String getName() {
         
  return 
   name;
    }

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

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   Teacher getTeacher() {
         
  return 
   teacher;
    }

     
  public 
    
  void 
   setTeacher(Teacher teacher) {
         
  this 
  .teacher  
  = 
   teacher;
    }
    @Override
     
  protected 
   Object clone()  
  throws 
   CloneNotSupportedException {
        Student student  
  = 
   (Student) 
  super 
  .clone();
        student.setTeacher((Teacher)student.getTeacher().clone());
         
  return 
    
  student 
  ;
    }
}


测式类同上:

测结果如下:

5
Student zhangsan
~~~~~~~~~~~~~~~~~~~~~~
21
Teacher Zhang
~~~~~~~~~~~~~~~~~~~~~~
21
Teacher Zhang

深克隆(二):采用可序列化的形式实现深克隆。

教师类如下:(实现Serializable接口)

 


public 
    
  class 
   Teacher  
  implements 
   Serializable {
     
  private 
    
  static 
    
  final 
    
  long 
   serialVersionUID  
  = 
    
  1L 
  ;
     
  public 
    
  int 
   age;
     
  public 
   String name;

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   String getName() {
         
  return 
   name;
    }

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


学生类如下:(实现Serializable接口)

 

import 
   java.io.ByteArrayInputStream;
 
  import 
   java.io.ByteArrayOutputStream;
 
  import 
   java.io.IOException;
 
  import 
   java.io.ObjectInputStream;
 
  import 
   java.io.ObjectOutputStream;
 
  import 
   java.io.Serializable;

 
  public 
    
  class 
   Student  
  implements 
   Serializable {

     
  // 
   serialVersionUID
     
  // 
   如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。
     
  // 
   但当serialVersionUID相同时,它就会将不一样的field以type的缺省值赋值(如int型的是0,String型的是null等),这个可以避开不兼容性的问题。所以最好给serialVersionUID赋值 
  
 
       
  private 
    
  static 
    
  final 
    
  long 
   serialVersionUID  
  = 
    
  1L 
  ;
     
  public 
   String name;
     
  public 
    
  int 
   age;
     
  public 
   Teacher teacher;

     
  public 
   String getName() {
         
  return 
   name;
    }

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

     
  public 
    
  int 
   getAge() {
         
  return 
   age;
    }

     
  public 
    
  void 
   setAge( 
  int 
   age) {
         
  this 
  .age  
  = 
   age;
    }

     
  public 
   Teacher getTeacher() {
         
  return 
   teacher;
    }

     
  public 
    
  void 
   setTeacher(Teacher teacher) {
         
  this 
  .teacher  
  = 
   teacher;
    }

     
  public 
   Object deepCopy()  
  throws 
   IOException, ClassNotFoundException {
         
  // 
   将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝 
  
 
          ByteArrayOutputStream bos  
  = 
    
  new 
   ByteArrayOutputStream();
        ObjectOutputStream oos  
  = 
    
  new 
   ObjectOutputStream(bos);
        oos.writeObject( 
  this 
  );
         
  // 
  将流序列化成对象  
  
 
          ByteArrayInputStream bis  
  = 
    
  new 
   ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois  
  = 
    
  new 
   ObjectInputStream(bis);
         
  return 
   ois.readObject();

    }
}

测试类:是把上面的测试类中的student1.clone()改成student1.deepCopy();执行。

测试结果如下:

12
Student zhangsan
~~~~~~~~~~~~~~~~~~~~~~
21
Teacher Zhang
~~~~~~~~~~~~~~~~~~~~~~
21
Teacher Zhang