浅复制和深复制
浅复制:
结论: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; } }
Aimer,c'est partager