拷贝,字面理解就是为了获得一份相同的数据。顾名思义就是为了获得一个相同的对象,而不需要我们再人为的创建和赋值。
在Java中如何理解深拷贝和浅拷贝呢?它们的区别又是什么?
1.1 浅拷贝
对基本数据类型进行值传递,对引用数据类型是引用地址值拷贝,此为浅拷贝。
1.2 深拷贝
** 对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。**
1.3 代码实现
package com.apps.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*
java中的拷贝需要实现java.lang.Cloneable接口,
然后重写clone()方法,这个无论深、浅拷贝都需要这样做
类要想可序列化就需要实现java.io.Serializable接口,
Cloneable、Serializable相当于标识,有这个标识才能使用Object的方法拷贝
*/
class Student implements Cloneable,Serializable { //学生类
public String name;
public int age;
public School s;
public Student() {
super();
}
public Student(String name, int age, School s) {
super();
this.name = name;
this.age = age;
this.s = s;
}
//使用Object()的clone()方法完成浅拷贝
public Student shallowClone() throws CloneNotSupportedException {
//调用父类的clone()方法,它是浅拷贝操作
return (Student) super.clone();
}
//使用序列化来完成深拷贝
public Student deepClone() throws Exception {
//序列化
FileOutputStream fos = new FileOutputStream("./sequence.hk");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(shallowClone());
//反序列化
FileInputStream fis = new FileInputStream("./sequence.hk");
ObjectInputStream ois = new ObjectInputStream(fis);
return (Student) ois.readObject();
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", s=" + s + "]";
}
}
class School implements Serializable { //学校类
public String name;
public int number;
public School() {
super();
}
public School(String name, int number) {
super();
this.name = name;
this.number = number;
}
@Override
public String toString() {
return "School [name=" + name + ", number=" + number + "]";
}
}
public class Demo {
public static void main(String [] args) throws Exception{
//浅拷贝
School sch = new School("清华大学",200000);
Student stu = new Student("张三",20,sch);
//调用方法
Student stu2 = stu.shallowClone();
System.out.println(stu);
System.out.println(stu2);
//修改stu的引用属性
stu.s.number = 300000;
System.out.println(stu);
System.out.println(stu2);
/* 打印结果
Student [name=张三, age=20, s=School [name=清华大学, number=200000]]
Student [name=张三, age=20, s=School [name=清华大学, number=200000]]
Student [name=张三, age=20, s=School [name=清华大学, number=300000]]
Student [name=张三, age=20, s=School [name=清华大学, number=300000]]
*/
可以看到我们修改stu的引用属性,发现stu2也跟着发生了修改,这就是浅拷贝
System.out.println("----------------------");
//深拷贝
School sch2 = new School("哈佛大学",500000);
Student stu3 = new Student("王二",20,sch2);
//调用方法
Student stu4 = stu3.deepClone();
System.out.println(stu3);
System.out.println(stu4);
//修改stu的引用属性
stu3.s.number = 600000;
System.out.println(stu3);
System.out.println(stu4);
/* 打印结果
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]
Student [name=王二, age=20, s=School [name=哈佛大学, number=600000]]
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]
*/
可以看到我们修改stu3的引用属性,发现stu4并没有发生了修改,这就是深拷贝
}
}