您的位置:

Java复制对象详解

一、对象复制的基本概念

对象复制是指在程序设计过程中将一个对象的内容(包括它所引用的其他对象)复制到另一个对象中。在Java中,对象复制分为深拷贝和浅拷贝两种方式。

二、Java实现对象复制的方式

1、Cloneable接口实现对象复制

对于Java中的深浅拷贝,Java提供了一个Cloneable接口,实现该接口的类可以使用Object类的clone方法来获取该对象的一个副本,但是需要注意的是,clone方法是protected类型,需要在子类中重写此方法实现浅拷贝或深拷贝。

class Person implements Cloneable {
    private String name;
    private int age;
    private ArrayList hobbies;

    // 构造方法省略

    // 重写clone方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person p = (Person) super.clone();
        // 对hobbies进行深拷贝
        p.hobbies = (ArrayList
   ) this.hobbies.clone();
        return p;
    }
}

// 调用方式
Person p1 = new Person("Tom", 18);
p1.addHobby("swimming");
Person p2 = (Person) p1.clone();
System.out.println(p2.getName()); // Tom
System.out.println(p2.getAge()); // 18
System.out.println(p2.getHobbies().size()); // 1

   
  

2、序列化实现对象复制

另一种实现对象复制的方式是使用Java的序列化(Serialization)机制。序列化将对象转换成一个字节序列,可以在网络上传输或在各层之间传递,也可以将其保存到本地文件中。反序列化就是将字节序列还原成对象,因此可以使用序列化实现对象的深拷贝。需要注意的是,被复制的对象及其引用类型需要实现Serializable接口。

class Person implements Serializable {
    private String name;
    private int age;
    private ArrayList hobbies;

    // 构造方法省略

    // 对象深拷贝方法
    public Person clone() throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Person) ois.readObject();
    }
}

// 调用方式
Person p1 = new Person("Tom", 18);
p1.addHobby("swimming");
Person p2 = p1.clone();
System.out.println(p2.getName()); // Tom
System.out.println(p2.getAge()); // 18
System.out.println(p2.getHobbies().size()); // 1

  

三、浅拷贝与深拷贝

1、浅拷贝

浅拷贝是指复制对象时,仅仅是对对象中的基本数据类型进行复制,而引用类型只是对其引用进行了复制,没有实现深拷贝。在Java中,使用Cloneable接口实现浅拷贝时,需要注意对引用类型进行特别处理。

class Person implements Cloneable {
    private String name;
    private int age;
    private ArrayList hobbies;

    // 构造方法省略

    // 重写clone方法
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 调用方式
Person p1 = new Person("Tom", 18);
p1.addHobby("swimming");
Person p2 = (Person) p1.clone();
System.out.println(p2.getName()); // Tom
System.out.println(p2.getAge()); // 18
System.out.println(p2.getHobbies().size()); // 1

  

2、深拷贝

深拷贝是指将复制对象中的基本数据类型和其引用类型均进行复制。实现深拷贝的方法主要有两种,一种是使用Cloneable接口,另一种是使用序列化,需要注意对引用类型的处理。

参见前文代码示例。

总结

本文从对象复制的基本概念、Java实现对象复制的方式、深浅拷贝等多个方面对Java复制对象做了详细的阐述。对于Java中的对象复制,需要根据具体需求选择实现深拷贝或浅拷贝的方式。