Java 语言 浅拷贝与深拷贝实现 手动复制与序列化拷贝

Java阿木 发布于 27 天前 5 次阅读


摘要:

在Java编程中,对象的复制是一个常见的需求。根据复制对象时是否复制对象内部引用,可以分为浅拷贝和深拷贝。本文将深入探讨Java中浅拷贝与深拷贝的实现方法,包括手动复制和序列化拷贝两种技术,并分析其优缺点。

一、

在Java中,对象的复制可以分为浅拷贝和深拷贝。浅拷贝是指复制对象时,只复制对象本身,而不复制对象内部的引用类型字段。深拷贝则是指复制对象时,不仅复制对象本身,还要复制对象内部的引用类型字段。本文将详细介绍这两种复制技术的实现方法。

二、浅拷贝与深拷贝的概念

1. 浅拷贝

浅拷贝是指创建一个新对象,然后将原对象的非静态字段值复制到新对象中。如果原对象中有引用类型字段,则新对象和原对象将共享这些引用。

2. 深拷贝

深拷贝是指创建一个新对象,然后将原对象的非静态字段值复制到新对象中。如果原对象中有引用类型字段,则新对象将复制这些引用类型字段,而不是共享它们。

三、手动复制实现浅拷贝与深拷贝

1. 手动复制实现浅拷贝

手动复制实现浅拷贝可以通过构造函数或克隆方法来完成。以下是一个简单的示例:

java

public class Person implements Cloneable {


private String name;


private Address address;

public Person(String name, Address address) {


this.name = name;


this.address = address;


}

@Override


protected Object clone() throws CloneNotSupportedException {


return super.clone();


}

public static void main(String[] args) {


Address address = new Address("Beijing", "China");


Person person = new Person("Alice", address);


Person clone = (Person) person.clone();


System.out.println("Original: " + person);


System.out.println("Clone: " + clone);


}


}

class Address {


private String city;


private String country;

public Address(String city, String country) {


this.city = city;


this.country = country;


}

@Override


public String toString() {


return "Address{" +


"city='" + city + ''' +


", country='" + country + ''' +


'}';


}


}


2. 手动复制实现深拷贝

手动复制实现深拷贝需要创建一个新对象,并手动复制所有字段,包括引用类型字段。以下是一个示例:

java

public class Person implements Cloneable {


private String name;


private Address address;

public Person(String name, Address address) {


this.name = name;


this.address = address;


}

@Override


protected Object clone() throws CloneNotSupportedException {


Person clone = (Person) super.clone();


clone.address = new Address(address.getCity(), address.getCountry());


return clone;


}

public static void main(String[] args) {


Address address = new Address("Beijing", "China");


Person person = new Person("Alice", address);


Person clone = (Person) person.clone();


System.out.println("Original: " + person);


System.out.println("Clone: " + clone);


}


}


四、序列化拷贝实现浅拷贝与深拷贝

1. 序列化拷贝实现浅拷贝

通过序列化和反序列化可以实现浅拷贝。以下是一个示例:

java

import java.io.;

public class Person implements Serializable {


private String name;


private Address address;

public Person(String name, Address address) {


this.name = name;


this.address = address;


}

public static Person clone(Person person) throws IOException, ClassNotFoundException {


ByteArrayOutputStream bos = new ByteArrayOutputStream();


ObjectOutputStream oos = new ObjectOutputStream(bos);


oos.writeObject(person);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());


ObjectInputStream ois = new ObjectInputStream(bis);


return (Person) ois.readObject();


}

public static void main(String[] args) {


try {


Address address = new Address("Beijing", "China");


Person person = new Person("Alice", address);


Person clone = Person.clone(person);


System.out.println("Original: " + person);


System.out.println("Clone: " + clone);


} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();


}


}


}

class Address implements Serializable {


private String city;


private String country;

public Address(String city, String country) {


this.city = city;


this.country = country;


}

@Override


public String toString() {


return "Address{" +


"city='" + city + ''' +


", country='" + country + ''' +


'}';


}


}


2. 序列化拷贝实现深拷贝

序列化拷贝实现深拷贝与浅拷贝类似,只是需要确保所有字段都被正确复制。以下是一个示例:

java

public class Person implements Serializable {


private String name;


private Address address;

public Person(String name, Address address) {


this.name = name;


this.address = address;


}

public static Person clone(Person person) throws IOException, ClassNotFoundException {


ByteArrayOutputStream bos = new ByteArrayOutputStream();


ObjectOutputStream oos = new ObjectOutputStream(bos);


oos.writeObject(person);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());


ObjectInputStream ois = new ObjectInputStream(bis);


Person clone = (Person) ois.readObject();


clone.address = new Address(clone.address.getCity(), clone.address.getCountry());


return clone;


}

public static void main(String[] args) {


try {


Address address = new Address("Beijing", "China");


Person person = new Person("Alice", address);


Person clone = Person.clone(person);


System.out.println("Original: " + person);


System.out.println("Clone: " + clone);


} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();


}


}


}


五、总结

本文详细介绍了Java中浅拷贝与深拷贝的实现方法,包括手动复制和序列化拷贝两种技术。手动复制需要开发者手动实现复制逻辑,而序列化拷贝则利用Java的序列化机制来实现对象的复制。在实际开发中,应根据具体需求选择合适的复制方法。

注意:本文中的代码示例仅供参考,实际应用中可能需要根据具体情况进行调整。