深浅拷贝:clone
java中的Object类中的方法.:
只用子类实现了Cloneable接口后,才可以使用Object类提供的clone方法
protected native Object clone() throws CloneNotSupportedException
-
异常
-
CloneNotSupportedException
表明该clone类方法Object被称为克隆对象,但该对象的类无法实现Cloneable接口。
要想让对象具有拷贝功能,必须实现Cloneable接口(表示接口,表示此类允许被拷贝clone),并且在类中自定义克隆方法,调用Object类提供的继承权限clone方法
浅拷贝 - 对象值拷贝
对于浅拷贝而言:拷贝出来的对象保留原对象的所有引用.,注意这里指的是引用
问题:牵一发而动全身.
只要任意一个拷贝对象(或原对象)中的引用发生改变,所有对象均会受到影响.
深拷贝
拷贝出来的对象产生了所有引用的新对象
特点:修改任意一个对象,不会对其他对象产生影响.
实现深拷贝的两种方法:
- 1.包含的其他类继续实现Cloneable接口,并且调用clone方法(递归实现Clone),也就是说一个对象实例,要复制他的所有属性,就需要属性类也实现Cloneable接口.并且调用super.clone()方法.
深浅拷贝的可以通过,是否在clone方法中有 student.teacher = (Teacher) teacher.clone();
import javax.swing.*;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.*;
//Teacher实现Cloneable接口
class Teacher implements Cloneable {
private String name;
private String job;
public Teacher clone() throws CloneNotSupportedException {
Teacher teacher = null;
teacher = (Teacher) super.clone();
return teacher;
}
public Teacher(String name, String job) {
this.name = name;
this.job = job;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
//Student实现Cloneable接口
class Student implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public Teacher getTeacher() {
return teacher;
}
public Student(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student clone() throws CloneNotSupportedException {
Student student = null;
student = (Student) super.clone();
student.teacher = this.teacher.clone();
return student;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Copy {
public static void main(String[] args) throws Exception {
Teacher teacher = new Teacher("ming","java Teacher");
Student student = new Student("zhan",18,teacher);
//创建一个Student实例
Student student1 = student.clone();
System.out.println(student.getTeacher());
System.out.println(student1.getTeacher());
}
}
- 2.使用序列化(重要)
使用序列化进行深拷贝时,无须再是实现Cloneable接口,只需要实现Serizalizable即可.
public Object deepClone() throws Exception
{
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}