java详解浅复制和深复制

一.简介

⑴浅复制(浅克隆)

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 

⑵深复制(深克隆)

被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。  

二.测试与实现

1.实现步骤:

①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。 
②在派生类中覆盖基类的clone()方法,并声明为public。 
③在派生类的clone()方法中,调用super.clone()。 
④在派生类中实现Cloneable接口。

2.测试代码:

职位类

package designPatterns.createPattern.copy;
import java.io.Serializable;

public class Profession implements Serializable {
    private static final long serialVersionUID = 9051L;
    private String position;//职位的名称

    public Profession(String position) {
        this.position = position;
    }

    public String getPosition() {
        return position;
    }
    public void setPosition(String position) {
        this.position = position;
    }
}

人的实体类

package designPatterns.createPattern.copy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class People implements Cloneable, Serializable {
    private static final long serialVersionUID = 9050L;

    private String name;
    private int age;
    private Profession profession = new Profession();

    public People(String name, int age, Profession profession) {
        this.name = name;
        this.age = age;
        this.profession = profession;
    }

    //浅复制
    public Object clone() {
        People people = null;
        try {
            people = (People) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return people;
    }

    //利用串行化来做深复制
    public Object deepClone() throws IOException, ClassNotFoundException {
        // 将对象写到流里
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(this);
        // 从流里读出来
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (oi.readObject());
    }

    // 用于展示类的字段信息
    public void printPeopleInfo() {
        System.out.println("name:" + name + "\tage:" + age + "\tprofession:" + profession.getPosition());
    }

    public Profession getProfession() {
        return profession;
    }
}

测试一:浅复制

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        People a = new People("ins", 24, new Profession("programmer"));
        People b = (People) a.clone();
        //打印结果
        a.printPeopleInfo();
        b.printPeopleInfo();
        //对职位修改
        a.getProfession().setPosition("manager");
        //打印结果
        a.printPeopleInfo();
        b.printPeopleInfo();
    }

}

测试一结果:

name:ins    age:24  profession:programmer
name:ins    age:24  profession:programmer
name:ins    age:24  profession:manager
name:ins    age:24  profession:manager

测试二:深复制

    public static void main(String[] args) throws ClassNotFoundException, IOException {
        People a = new People("ins", 24, new Profession("programmer"));
        People b = (People) a.deepClone();
        //打印结果
        a.printPeopleInfo();
        b.printPeopleInfo();
        //对职位修改
        a.getProfession().setPosition("manager");
        //打印结果
        a.printPeopleInfo();
        b.printPeopleInfo();
    }

测试二结果:

name:ins    age:24  profession:programmer
name:ins    age:24  profession:programmer
name:ins    age:24  profession:manager
name:ins    age:24  profession:programmer

三.备注与总结

深复制,之所以采用串行化做的原因是为了避免重写比较复杂对象的深复制的clone()方法,也可以程序实现断点续传等等功能.
由上面的代码和结果可以更加直接的理解浅克隆和深克隆.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值