扫码关注微信公众号

回复“面试手册”,获取本站PDF版

回复“简历”,获取高质量简历模板

回复“加群”,加入程序员交流群

回复“电子书”,获取程序员类电子书

当前位置: Java > Java基础高频面试题 > 46. 深拷贝与浅拷贝 
  • 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,两个引用指向两个对象,但对象内容相同。
  • 浅拷贝:对基本数据类型进行值传递,对引用数据类型复制一个引用指向原始引用的对象,就是复制的引用和原始引用指向同一个对象。

具体区别看下图

深拷贝与浅拷贝
深拷贝与浅拷贝
  • 深拷贝的实现方式
  1. 重载clone方法
 public class Main{
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, CloneNotSupportedException {
        Address s = new Address("天津");
        Person p = new Person("张三", 23, s);
        System.out.println("克隆前的地址:" + p.getAddress().getName());
        Person cloneP = (Person) p.clone();
        cloneP.getAddress().setName("北京");
        System.out.println("克隆后的地址:" + cloneP.getAddress().getName());
    }
}

class Address implements Cloneable {
    private String city;
    public Address(String name){
        this.city = name;
}
    @Override
    protected Object clone() throws CloneNotSupportedException {
            return super.clone();
    }
    public String getName() {
        return city;

    }
    public void setName(String name) {
        this.city = name;

    }
}
class Person implements Cloneable{
    private String name;
    private int age;
    private Address address;
    public Person(String name, int age, Address address){
        this.name = name;
        this.age = age;
        this.address = address;

    }
    @Override
    public Object clone() throws CloneNotSupportedException {
          Person  person = (Person) super.clone();
          person.address = (Address)address.clone();
        return person;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}

输出

克隆前的地址:天津
克隆后的地址:北京

其实就是Person类和Address类都要重写clone方法,这里面需要注意的一点是super.clone()为浅克隆,所以在在Person类中重写clone方法时,address对象需要调用address.clone()重新赋值,因为address类型为引用类型。

2.序列化

public class Main{
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Address s = new Address("天津");
        Person p = new Person("张三", 23, s);
        System.out.println("克隆前的地址:" + p.getAddress().getName());
        Person cloneP = (Person) p.deepClone();
        cloneP.getAddress().setName("北京");
        System.out.println("克隆后的地址:" + cloneP.getAddress().getName());
    }
}

class Address implements Serializable{
    private String city;
    public Address(String name){
        this.city = name;
    }

    public String getName() {
        return city;

    }
    public void setName(String name) {
        this.city = name;

    }
}
class Person implements Serializable{
    private String name;
    private int age;
    private Address address;
    public Person(String name, int age, Address address){
        this.name = name;
        this.age = age;
        this.address = address;

    }

    public Object deepClone() throws IOException, ClassNotFoundException {        
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);        
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}

输出

克隆前的地址:天津
克隆后的地址:北京

点击面试手册,获取本站面试手册PDF完整版