浅拷贝和深拷贝的整理


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

/**
 * 浅拷贝:
 * 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制。
 * 如果该字段是引用类型的话,则复制引用但不复制引用的对象,因此,原始对象及其副本引用同一个对象。
 * 实现浅拷贝的方式:
 * 对象实现cloneable接口,实现clone()方法
 *
 * 深拷贝:
 * 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型还是引用类型都是复制独立的一份。
 * 当你修改其中一个对象的任何内容时,都不会影响另一个对象的内容。
 *
 * 实现深拷贝的方法
 * 1)让每一个引用类型属性内部都重写clone()方法。此方法有个缺点:如果有多个引用类型,必须重写多次。
 * 2)利用序列化
 * 序列化是将对象写到流中便于传输,而反序列化则是把对象从流中读取出来。这里写到流中的对象则是原始对象的一个拷贝,因为原始对象还存在
 * JVM中,所有利用对象的序列化产生克隆对象,通过反序列化获取这个对象。
 *
 */
public class TestCopy {

    public static void main(String[] args) throws Exception{
        Person p1=new Person("sunyuhua",22);
        p1.setAddress("山东省","潍坊市");
        System.out.println(p1);
        System.out.println(p1.getPname().hashCode());
        Person p2=(Person)p1.clone();
        System.out.println(p2);
        System.out.println(p2.getPname().hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.equals(p2));
        p1.display("p1");
        p2.display("p2");
        p2.setAddress("上海","浦东");
        System.out.println(p1.getPname().hashCode());
        System.out.println(p2.getPname().hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.equals(p2));
        p1.display("p1");
        p2.display("p2");

        System.out.println("深拷贝深拷贝深拷贝深拷贝深拷贝深拷贝");
        DeepPerson deepPerson1=new DeepPerson("sunyuhua",22);
        deepPerson1.setAddress("山东省","潍坊市");
        System.out.println(deepPerson1);
        System.out.println(deepPerson1.getPname().hashCode());
        DeepPerson deepPerson2=(DeepPerson)deepPerson1.clone();
        System.out.println(deepPerson2);
        System.out.println(deepPerson2.getPname().hashCode());
        System.out.println(deepPerson1==deepPerson2);
        System.out.println(deepPerson1.equals(deepPerson2));
        deepPerson1.display("deepPerson1");
        deepPerson2.display("deepPerson2");
        deepPerson2.setAddress("上海","浦东");
        System.out.println(deepPerson1.getPname().hashCode());
        System.out.println(deepPerson2.getPname().hashCode());
        System.out.println(deepPerson1==deepPerson2);
        System.out.println(deepPerson1.equals(deepPerson2));
        p1.display("deepPerson1");
        p2.display("deepPerson2");
        System.out.println("深拷贝深拷贝深拷贝深拷贝深拷贝深拷贝");
        System.out.println("利用序列化利用序列化利用序列化利用序列化");
        Person person1=new Person("sunyuhua",22);
        person1.setAddress("山东省","潍坊市");
        System.out.println(person1);
        System.out.println(person1.getPname().hashCode());
        Person person2=(Person) deepClone(person1);
        System.out.println(person2);
        System.out.println(person2.getPname().hashCode());
        System.out.println(person1==person2);
        System.out.println(person1.equals(person2));
        deepPerson1.display("person1");
        deepPerson2.display("person2");
        deepPerson2.setAddress("上海","浦东");
        System.out.println(person1.getPname().hashCode());
        System.out.println(person2.getPname().hashCode());
        System.out.println(person1==person2);
        System.out.println(person1.equals(person2));
        p1.display("person1");
        p2.display("person2");
    }

    /**
     * 对象深复制的方法
     * @param person
     * @return
     * @throws Exception
     */
    public static Object deepClone(Person person) throws Exception{
        //将对象进行序列化
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(person);
        //将对象反序列化
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream=new ObjectInputStream(byteArrayInputStream);
        return objectInputStream.readObject();
    }

}

/**
 * 实现浅拷贝
 */
@Data
public class Person implements Cloneable, Serializable {
    public String pname;
    public int page;
    public Address address;

    public Person(String pname,int page){
        this.pname=pname;
        this.page=page;
        this.address=new Address();
    }

    public void setAddress(String provices,String city){
        address.setAddress(provices,city);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public void display(String name){
        System.out.println("name="+pname+",page="+page+"address="+address.toString());
    }
}

package com.chen.www.chendemo.objectCopy;

import java.io.Serializable;

public class Address implements Serializable {
    private String provices;
    private String city;
    public void setAddress(String provices,String city){
        this.provices=provices;
        this.city=city;
    }

    @Override
    public String toString() {
        return "address==provices="+provices+"city="+city;
    }
}


/**
 * 让每一个引用类型属性内部都重写clone()方法。
 * 既然引用类型不能实现深拷贝,那么我们将每个引用类型都拆分为基本类型,分别进行浅拷贝。
 */
public class DeepAddress implements Cloneable{
    private String provices;
    private String city;
    public void setAddress(String provices,String city){
        this.provices=provices;
        this.city=city;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "address==provices="+provices+"city="+city;
    }
}


import lombok.Data;

@Data
public class DeepPerson implements Cloneable{
    public String pname;
    public int page;
    public DeepAddress deepAddress;

    public DeepPerson(String pname,int page){
        this.pname=pname;
        this.page=page;
        this.deepAddress=new DeepAddress();
    }

    public void setAddress(String provices,String city){
        deepAddress.setAddress(provices,city);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        DeepPerson person=(DeepPerson)super.clone();
        person.deepAddress=(DeepAddress)deepAddress.clone();
        return person;
    }

    public void display(String name){
        System.out.println("name="+pname+",page="+page+"address="+deepAddress.toString());
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值