首页 > 开发 > Java > 正文

Java对象深复制与浅复制实例详解

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

 Java对象深复制与浅复制实例详解

我们在遇到一些业务场景的时候经常需要对对象进行复制,对于对象的复制一般有两种方式,深复制和浅复制

浅复制:对象的复制仅是对象本身,对象引用的其它对方并不会复制。

深复制:对象的复制包含对象引用的对象。

Java所有对象的基类提供了clone方法,但是这个方法是protected native修饰,因此只暴露给之类去重写,外部是无法直接调用的。

我们现在来测试两种复制,首选是浅复制,浅复制要实现Cloneable接口。

// 课程对象class Class {  private String name;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }}// 学生对象class User implements Cloneable {  private String name;  private Long id;  // 课程引用  private Class c;  public Class getC() {    return c;  }  public void setC(Class c) {    this.c = c;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public Long getId() {    return id;  }  public void setId(Long id) {    this.id = id;  }  @Override  protected Object clone() throws CloneNotSupportedException {    return super.clone();  }  @Override  public int hashCode() {    return super.hashCode();  }  @Override  public boolean equals(Object obj) {    if (obj instanceof User) {      User user = (User) obj;      if (this.id == user.getId() && this.getName() == user.getName()) {        return true;      }      if (user.getId().equals(this.id)          && user.getName().equals(this.name)) {        return true;      }      return false;    } else      return false;  }}

我们来测试:

 User user1 = new User();    User user2 = user1;    User user3 = (User) user1.clone();    System.out.println(user1 == user2);    System.out.println(user3 == user1);    System.out.println(user3.equals(user1));    System.out.println(user3.getName() == user3.getName());// true,浅复制    Class c = new Class();    c.setName("语文");    user1.setC(c);    // 测试复制深度    User user4 = (User) user1.clone();    System.out.println(user4.getC() == user1.getC()); // true,说明引用的对象依然是同一个对象

对象的复制并没复制引用所指向的对象class,复制出来的引用指向的同一个地址。

深复制采用序列化与反序列的方式去获取,也有种说法类似于腌菜,用流的方式腌制进去又取出来,实现深度复制。

class Car implements Serializable {  /**   *    */  private static final long serialVersionUID = 42342L;  private String name;  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }}// 深复制class People implements Serializable{  /**   *    */  private static final long serialVersionUID = 543535212412L;  private Car car;  public Car getCar() {    return car;  }  public void setCar(Car car) {    this.car = car;  }  public People deepClone() throws IOException, ClassNotFoundException {    // 腌制    ByteArrayOutputStream out = new ByteArrayOutputStream();    ObjectOutputStream oos = new ObjectOutputStream(out);    oos.writeObject(this);    // 取出    ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());    ObjectInputStream ois = new ObjectInputStream(input);    return (People) ois.readObject();  }}

测试深复制:

// 深复制    Car car = new Car();    car.setName("benz");    People p = new People();    p.setCar(car);    try {      People p2 = p.deepClone();      System.out.println(p2.getCar() == p.getCar()); // false,说明引用的对象也进行了复制    } catch (ClassNotFoundException | IOException e) {      e.printStackTrace();    }

例外提及一下生成对象的五种办法:

1.new
2.Class类的newInstance
3.Constructor类newInstance
4.Clone方式
5.反序列化的方式

其中2与3即是反射的方式。

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


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