淺拷貝是指拷貝對(duì)象時(shí)僅僅拷貝對(duì)象本身(包括對(duì)象中的基本變量),而不拷貝對(duì)象包含的引用指向的對(duì)象。深拷貝不僅拷貝對(duì)象本身,而且拷貝對(duì)象包含的引用指向的所有對(duì)象。舉例來(lái)說(shuō)更加清楚:對(duì)象A1中包含對(duì)B1的引用,B1中包含對(duì)C1的引用。淺拷貝A1得到A2,A2 中依然包含對(duì)B1的引用,B1中依然包含對(duì)C1的引用。深拷貝則是對(duì)淺拷貝的遞歸,深拷貝A1得到A2,A2中包含對(duì)B2(B1的copy)的引用,B2 中包含對(duì)C2(C1的copy)的引用。
package Clone;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: CopyDemo
* @Author sandy.n.hao
* @Date: 2019-07-10
* @Version v1.0.0
* @Description: //TODO
*/
public class CopyDemo {
public static void main(String[] args) {
Person p1 = new Person("Sandy",18);
Person p2 = new Person("Monica",20);
Map<String,Object> map1= new HashMap();
Map<String,Object> temp= new HashMap();
map1.put("first",p1);
temp.put("temp","temp");
Map<String,Object> map2 = new HashMap();
Map<String,Object> map3 = new HashMap();
System.out.println("拷貝前:");
System.out.println("map1: "+map1);
System.out.println("map2: "+map2);
System.out.println("map3: "+map3);
/*
* 淺拷貝
*/
map2.putAll(map1);
/*
* 深拷貝
*/
map3 = Utils.DeepClone(map1);
//拷貝后
System.out.println("拷貝結(jié)果:");
System.out.println("map1: "+map1);
System.out.println("map2: "+map2);
System.out.println("map3: "+map3);
// ((Map)(map1.get("first"))).put("final","final");
((Person)(map1.get("first"))).setName("Coco");
((Person)(map1.get("first"))).setAge(20);
System.out.println("修改后:");
System.out.println("map1: "+map1);
System.out.println("map2: "+map2);
System.out.println("map3: "+map3);
}
/*
內(nèi)部類實(shí)現(xiàn)序列化
*/
public static class Person implements Serializable
{
private static final long serialVersionUID = 8656128222714547171L;
transient private String name;
private int age;
Person(String name,int age){
this.name= name;
this.age=age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
package com.sandy.DeepAndShallowCopy;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Utils {
public static <T extends Serializable> T DeepClone (Object obj){
T cloneObj = null;
try{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.close();
ByteInputStream byteInputStream = new ByteInputStream(byteArrayOutputStream.toByteArray(),byteArrayOutputStream.size());
ObjectInputStream objectInputStream = new ObjectInputStream(byteInputStream);
cloneObj = (T) objectInputStream.readObject();
objectInputStream.close();
}catch (Exception e){
e.printStackTrace();
}
return cloneObj;
}
}
輸出:
拷貝前:
map1: {first=Person{name='Sandy', age=18}}
map2: {}
map3: {}
拷貝結(jié)果:
map1: {first=Person{name='Sandy', age=18}}
map2: {first=Person{name='Sandy', age=18}}
map3: {first=Person{name='null', age=18}}
修改后:
map1: {first=Person{name='Coco', age=20}}
map2: {first=Person{name='Coco', age=20}}
map3: {first=Person{name='null', age=18}}
map3通過(guò)序列化的方式實(shí)現(xiàn)了深拷貝,name用transient,未進(jìn)行序列化,是實(shí)現(xiàn)深拷貝。