首页 > 开发 > Java > 正文

java 对象的克隆(浅克隆和深克隆)

2024-07-13 10:10:09
字体:
来源:转载
供稿:网友

javascript/83615.html">java 对象的克隆

一、对象的浅克隆

(1)需要克隆类需要重写Object类的clone方法,并且实现Cloneable接口(标识接口,无需实现任何方法)
(2)当需要克隆的对象中维护着另外一个引用对象,浅克隆不会克隆另外一个引用对下,而是直接复制维护的另外一个引用对象的地址。
(3)对象的浅克隆也不会调用到构造方法。

以下为对象的浅克隆的一个例子:

package com.clone;import java.io.Serializable;/** * Description: * 实现了Cloneable接口,并重写Object类的clone方法。 *  * @author lee * */public class CloneDemo1 implements Cloneable,Serializable{  //该克隆类封装的信息  public int id;  public String name;  public Address address;  /**   * Desciption:   * 默认构造器   *    * */  public CloneDemo1(){}  /**   * Description:   * 初始化id,name的构造器   *    * @param id id   * @param name 名字   * @param address 地址   * */  public CloneDemo1(int id, String name, Address address){    this.id=id;    this.name=name;    this.address = address;  }  /**   * Descriptin:   * 重写Object类的clone方法。   * if the object's class does not support the Cloneable interface.   * Subclasses that override the clone method can also throw this exception    * to indicate that an instance cannot be cloned.   *    * @throws CloneNotSupportedException    * */  @Override  public Object clone() throws CloneNotSupportedException{    return super.clone();  }  /**   * Description:   * 重写toString方法   *    * @return "id="+id+", name="+name   * */  @Override  public String toString(){    return "id="+id+", name="+name+", address:"+address.getAddress();  }  /**   * Description:   * 主方法   *    * */  public static void main(String[] args) throws CloneNotSupportedException{    CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));    //c2 复制了c1的地址,并没有复制整个c1对象    CloneDemo1 c2 = c1;    //c3 对象的浅克隆,复制了整个对象    CloneDemo1 c3 = (CloneDemo1)c1.clone();    //当对象c1改变其name或者id的时候,c2也会自动改变。    //因为c2只是复制了c1的地址,并非复制了c1的整个对象。    //相应的c3则不会随着c1改变而改变,意味着c3将c1整个对象克隆一份出来。    //当是,对象的浅克隆不会克隆被克隆对象当中的引用对象。    //因此c1改变其中的Address的引用对象时,c2,c3也会跟着改变。    c1.setName("cc");    c1.address.setAddress("上海");    System.out.println(c1+"/n"+c2+"/n"+c3);  }  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }}/** * Description: * 一个封装着地址的类 *  * @author lee * */class Address implements Serializable{  public String address;  /**   * Description:   * 默认构造器   *    * */  public Address(){}  /**   * Description:   * 初试化address   *    * @param address 地址   * */  public Address(String address){    this.address = address;  }  //address的set和get方法  public String getAddress() {    return address;  }  public void setAddress(String address) {    this.address = address;  }}

二、对象的深克隆

就是利用对象的输入输出流把对象写到文件上,再读取对象的信息,这就是对象的深克隆。

由于对象的浅克隆不会克隆被克隆对象其中的引用对象,而是直接复制其地址。因此,要克隆被克隆对象当中的引用类型则需要对象的深克隆。

而对象的深克隆使用的的对象序列化输入输出。

代码如下:

package com.clone;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/** * Description: * 实现对象的深克隆 *  * @author lee * */public class CloneDemo2 {  /**   * Description:   * 将对象输出到一个文件当中。   *    * @param c 需要被写到文件当中的对象。   * */  public static void writeObject(CloneDemo1 c){    ObjectOutputStream out = null;    try{      //将对象输出在一个object.txt文件当中      out = new ObjectOutputStream(new FileOutputStream("./object.txt"));      out.writeObject(c);    }catch(IOException e){      System.out.println("写入对象的时候发生了错误。");      e.printStackTrace();    }finally{      //关闭资源      try{        out.close();      }catch(IOException e){        e.printStackTrace();      }    }  }  /**   * Description:   * 从文件中读取出一个对象来,并返回。   *    * @return c 返回一个对象。   * */  public static CloneDemo1 readObject(){    CloneDemo1 c = null;    ObjectInputStream input = null;    try{      //从object.txt文件中读取一个对象出来      input = new ObjectInputStream(new FileInputStream("./object.txt"));      c = (CloneDemo1)input.readObject();    }catch(IOException | ClassNotFoundException e){      e.printStackTrace();      System.out.println("读取对象的时候发生了错误。");    }finally{      //关闭资源      try{        input.close();      }catch(IOException e){        e.printStackTrace();      }    }    return c;  }  /**   * Description:   * 主方法   *    * @throws CloneNotSupportedException    * */  public static void main(String[] args) throws CloneNotSupportedException {    CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));    //c2 对象的浅克隆    CloneDemo1 c2 = (CloneDemo1)c1.clone();    //c3对象的深克隆    writeObject(c1);    CloneDemo1 c3 = readObject();    //因为对象的深克隆同时也克隆了被克隆对象维护的另外一个对象    //所以,当c1改变其当中的维护的另外一个对象的时候,c3不会随之改变。    //而c2位浅克隆,其维护的另外一个对象只是复制了c1维护的对象的地址,因此会随着c1的改变而改变。    c1.address.setAddress("上海");    System.out.println(c1+"/n"+c2+"/n"+c3);  }}

对象的序列化,是需要实现Serializable接口的。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表