当前位置: 移动技术网 > IT编程>开发语言>Java > Java对象深复制与浅复制实例详解

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

 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即是反射的方式。

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网