浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对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("拷贝结果:");
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);
}
/*
内部类实现序列化
*/
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: {}
拷贝结果:
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通过序列化的方式实现了深拷贝,name用transient,未进行序列化,是实现深拷贝。