21xrx.com
2025-03-29 12:54:33 Saturday
文章检索 我的文章 写文章
Java中实现对象克隆的几种方法
2023-06-19 12:46:11 深夜i     --     --
Java 复制对象 clone()方法 序列化 Apache

Java中,如果需要给实例对象赋值,通常都是使用new关键字创建一个新的对象,然后一一将属性值赋值过去。但如果遇到一个已经存在的对象,需要通过复制该对象来创建新的对象,这时就需要实现对象克隆操作。本文将介绍几种Java中实现对象克隆的方法。

一、使用Object类的clone()方法

clone()方法是Object类提供的方法,该方法返回一个新的对象并复制原对象的所有属性,需要注意以下两点:

1.复制出来的对象与原对象不是同一对象,它们在内存中的地址是不同的。

2.要复制的对象必须实现Clonable接口,并且重写clone()方法,否则会抛出CloneNotSupportedException异常。

下面是一个实现深拷贝的例子:

public class Person implements Cloneable{
  private String name;
  private int age;
  private Address address;
  ...
  //重写clone()方法
  public Person clone() throws CloneNotSupportedException{
     Person person = (Person) super.clone();
     person.address = this.address.clone(); // 重点
     return person;
  }
}

二、使用序列化(Serialization)实现深克隆

Java中的序列化是指将一个对象转换成字节码,存储到文件或者通过网络传输到另一个地方。而反序列化就是将字节码还原成一个对象。因此,我们可以通过序列化出一个对象的字节码,再通过反序列化从字节码中获取一个新的对象,达到复制对象的目的。需要注意以下几点:

1.要求对象及其内部所包含的对象都必须实现java.io.Serializable 接口。

2.实现Serialization序列化和反序列化时,对象及其内部成员类的类定义都必须是public的,并且不能是匿名类和局部内部类。

3.需要提供一个输入输出流。

public class DeepCopyBySerialization {
  public static void main(String[] args) throws IOException, ClassNotFoundException {
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      oos = new ObjectOutputStream(baos);
      PersonDeepCopy person1 = new PersonDeepCopy();
      oos.writeObject(person1);
      oos.flush();
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ois = new ObjectInputStream(bais);
      PersonDeepCopy person2 = (PersonDeepCopy)ois.readObject();
      System.out.println(person1 == person2); //false
      System.out.println(person2);
    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    } finally {
      if (oos != null) {
        oos.close();
      }
      if (ois != null) {
        ois.close();
      }
    }
  }
}

三、使用Apache Commons Lang3库的SerializationUtils实现对象复制

Apache Commons Lang3是一个强大的开发库,提供了很多常用的工具类、方法和一些特殊的功能,可以广泛运用于Java编程中。其中的SerializationUtils就提供了一些序列化/反序列化相关的工具类,可以实现对象克隆。

public class DeepCopyWithUtils{
  public static void main(String[] args) {
    PersonDeepCopy po = new PersonDeepCopy();
    PersonDeepCopy p1 = SerializationUtils.clone(po);
    System.out.println(po == p1);//false
  }
}

Commons Lang3库。

  
  

评论区