浅复制和深复制

浅复制:

   结论:clone 方法
内存地址不一致,克隆的对象和原来的对象已经是两个不同的对象 基本类型 :原来的对象 和 clone的对象 已经完全互不影响 引用类型: 还是共享一个内存地址,所以一个改变,另一个还是会跟着改变 String:String是应用类型,但是因为是不变类,所以也不会有影响
package com.hella.thread.pattern.protoType;

import java.util.ArrayList;

public class ProtoType implements Cloneable {

    private String id;

    private int age;

    private boolean married;
    
    private ArrayList<Hobby> dd = new ArrayList<>();

    private Hobby hobby;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMarried() {
        return married;
    }

    public void setMarried(boolean married) {
        this.married = married;
    }

    public Hobby getHobby() {
        return hobby;
    }

    public void setHobby(Hobby hobby) {
        this.hobby = hobby;
    }

    @Override
    protected ProtoType clone() throws CloneNotSupportedException {
        //默认浅克隆
        ProtoType ProtoType = (ProtoType)super.clone();
        return ProtoType;
    }

}

class Hobby{

    private int hid;

    private String name;

    public int getHid() {
        return hid;
    }

    public void setHid(int hid) {
        this.hid = hid;
    }

    public String getName() {
        return name;
    }

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

测试:

public class App {
    public static void main(String[] args) throws Exception {
        ProtoType pType = new ProtoType();
        pType.setId("1"); // String 类型
        pType.setAge(20); // 基本数据类型
        pType.setMarried(false);// 基本数据类型
        Hobby hobby = new Hobby(); // 引用类型
        hobby.setHid(100);
        hobby.setName("basketball");
        pType.setHobby(hobby);
        
        System.out.println("==================原来对象=============================================");
        // 打印内存地址
        System.out.println(pType.hashCode()); // 366712642
        System.out.println(pType.getId()); // 1
        System.out.println(pType.getAge()); // 20
        System.out.println(pType.isMarried()); // false
        System.out.println(pType.getHobby().hashCode()); // 1829164700
        System.out.println(pType.getHobby().getHid()); // 100
        System.out.println(pType.getHobby().getName()); // basketball
        System.out.println("====================对象克隆===========================================");
        // clone
        ProtoType pTypeClone = pType.clone();
        System.out.println(pTypeClone.hashCode()); // 2018699554
        System.out.println(pTypeClone.getId()); // 1
        System.out.println(pTypeClone.getAge()); // 20
        System.out.println(pTypeClone.isMarried()); // false
        System.out.println(pTypeClone.getHobby().hashCode()); // 1829164700
        System.out.println(pTypeClone.getHobby().getHid()); // 100
        System.out.println(pTypeClone.getHobby().getName()); // basketball
        
        // 根据 pType和 pTypeClone 对比,发现内存地址不一样,说明 两个是不同的对象
        
        //更改复制过来的对象
        pTypeClone.setId("2");
        pTypeClone.setAge(30);
        pTypeClone.setMarried(true);
        pTypeClone.getHobby().setHid(200);
        pTypeClone.getHobby().setName("football");
        
        // clone对象重新设置
        System.out.println("=====================克隆对象重新设置后==========================================");
        System.out.println(pTypeClone.hashCode()); // 2018699554
        System.out.println(pTypeClone.getId()); // 2
        System.out.println(pTypeClone.getAge()); // 30
        System.out.println(pTypeClone.isMarried()); // true
        System.out.println(pTypeClone.getHobby().hashCode()); // 1829164700   浅克隆 引用类型内存中的地址没有变 一个改变,另一个也会相应的变化
        System.out.println(pTypeClone.getHobby().getHid()); // 200
        System.out.println(pTypeClone.getHobby().getName()); // football
        
        
        System.out.println("========================对来对象=======================================");
        //查看原来对象
        System.out.println(pType.hashCode()); // 366712642
        System.out.println(pType.getId()); // 1
        System.out.println(pType.getAge()); // 20
        System.out.println(pType.isMarried()); // false
        System.out.println(pType.getHobby().hashCode()); // 1829164700
        System.out.println(pType.getHobby().getHid()); // 200
        System.out.println(pType.getHobby().getName()); // football
        
        //原对象的引用类型的数据已经变类
        /*
         * 结论:clone 方法
         * 基本类型 :原来的对象 和 clone的对象 已经完全互不影响
         * 引用类型: 还是共享一个内存地址,所以一个改变,另一个还是会跟着改变
         * String:String是应用类型,但是因为是不变类,所以也不会有影响
         * 
         */

    }

}

深复制实现方式一:引用类型也分别clone

public class ProtoType implements Cloneable {

    private String id;

    private int age;

    private boolean married;
    
    private ArrayList<Hobby> dd = new ArrayList<>();

    private Hobby hobby;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMarried() {
        return married;
    }

    public void setMarried(boolean married) {
        this.married = married;
    }

    public Hobby getHobby() {
        return hobby;
    }

    public void setHobby(Hobby hobby) {
        this.hobby = hobby;
    }

    @Override
    protected ProtoType clone() throws CloneNotSupportedException {
        //默认浅克隆
        ProtoType ProtoType = (ProtoType)super.clone();
        //深复制
        Hobby clone = this.hobby.clone();
        ProtoType.hobby = clone;
        return ProtoType;
    }

}

class Hobby implements Cloneable{

    private int hid;

    private String name;

    public int getHid() {
        return hid;
    }

    public void setHid(int hid) {
        this.hid = hid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected Hobby clone() throws CloneNotSupportedException {
        return (Hobby)super.clone();
    }
}
public class App {
    public static void main(String[] args) throws Exception {
        ProtoType pType = new ProtoType();
        pType.setId("1"); // String 类型
        pType.setAge(20); // 基本数据类型
        pType.setMarried(false);// 基本数据类型
        Hobby hobby = new Hobby(); // 引用类型
        hobby.setHid(100);
        hobby.setName("basketball");
        pType.setHobby(hobby);
        
        System.out.println("==================原来对象=============================================");
        // 打印内存地址
        System.out.println(pType.hashCode()); // 366712642
        System.out.println(pType.getId()); // 1
        System.out.println(pType.getAge()); // 20
        System.out.println(pType.isMarried()); // false
        System.out.println(pType.getHobby().hashCode()); // 1829164700
        System.out.println(pType.getHobby().getHid()); // 100
        System.out.println(pType.getHobby().getName()); // basketball
        System.out.println("====================对象克隆===========================================");
        // clone
        ProtoType pTypeClone = pType.clone();
        System.out.println(pTypeClone.hashCode()); // 2018699554
        System.out.println(pTypeClone.getId()); // 1
        System.out.println(pTypeClone.getAge()); // 20
        System.out.println(pTypeClone.isMarried()); // false
        System.out.println(pTypeClone.getHobby().hashCode()); // 1311053135
        System.out.println(pTypeClone.getHobby().getHid()); // 100
        System.out.println(pTypeClone.getHobby().getName()); // basketball
        
        // 根据 pType和 pTypeClone 对比,发现内存地址不一样,说明 两个是不同的对象
        
        //更改复制过来的对象
        pTypeClone.setId("2");
        pTypeClone.setAge(30);
        pTypeClone.setMarried(true);
        pTypeClone.getHobby().setHid(200);
        pTypeClone.getHobby().setName("football");
        
        // clone对象重新设置
        System.out.println("=====================克隆对象重新设置后==========================================");
        System.out.println(pTypeClone.hashCode()); // 2018699554
        System.out.println(pTypeClone.getId()); // 2
        System.out.println(pTypeClone.getAge()); // 30
        System.out.println(pTypeClone.isMarried()); // true
        System.out.println(pTypeClone.getHobby().hashCode()); // 1311053135    引用类型深克隆之后内存中重新分配地址
        System.out.println(pTypeClone.getHobby().getHid()); // 200
        System.out.println(pTypeClone.getHobby().getName()); // football
        
        
        System.out.println("========================对来对象=======================================");
        //查看原来对象
        System.out.println(pType.hashCode()); // 366712642
        System.out.println(pType.getId()); // 1
        System.out.println(pType.getAge()); // 20
        System.out.println(pType.isMarried()); // false
        System.out.println(pType.getHobby().hashCode()); // 1829164700
        System.out.println(pType.getHobby().getHid()); // 200
        System.out.println(pType.getHobby().getName()); // football
        
        //原对象的引用类型的数据已经变类
        /*
         * 结论:clone 方法
         * 基本类型 :原来的对象 和 clone的对象 已经完全互不影响
         * 引用类型: 还是共享一个内存地址,所以一个改变,另一个还是会跟着改变
         * String:String是应用类型,但是因为是不变类,所以也不会有影响
         * 
         */

    }

}

 深复制实现方式二: 对象实现Serializable 接口,对象里面的对象也必须实现Serializable 

public class App {
    public static void main(String[] args) throws Exception {
        ProtoType protoType = new ProtoType();
        Hobby hobby = new Hobby();
        hobby.setId(1);
        hobby.setName("basketball");
        protoType.setUsername("Chris");
        protoType.setHobby(hobby);
        System.out.println(protoType.hashCode()); //366712642
        System.out.println(protoType.getHobby().hashCode()); //1829164700

        File file = new File("C:\Users\caich5\Desktop\a.txt");
        OutputStream outputStream = new FileOutputStream(file);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(protoType);// 366712642
        objectOutputStream.close();

        InputStream inputStream = new FileInputStream(file);
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        ProtoType protoTyleClone = (ProtoType) objectInputStream.readObject();
        objectInputStream.close();

        System.out.println(protoTyleClone.hashCode()); // 1149319664
        System.out.println(protoTyleClone.getHobby().hashCode());//2093631819
        
        protoTyleClone.getHobby().setName("football");
        
        System.out.println(protoType.getHobby().getName()); //basketball
        

    }

}
public class ProtoType implements Serializable {

    private String username;

    private Hobby hobby;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Hobby getHobby() {
        return hobby;
    }

    public void setHobby(Hobby hobby) {
        this.hobby = hobby;
    }
    

}

class Hobby implements Serializable{

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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



}
原文地址:https://www.cnblogs.com/pickKnow/p/11104193.html