深浅拷贝
一、深浅拷贝(对象)
浅拷贝:复制了一个新对象,里面的内容是值拷贝。对于引用类型,不管拷贝多少次都指向原来的类;
Cloneable:CloneNotSuportedException
只有子类实现了Cloneable接口后才可以使用object类提供的clone方法。
protecte native Object clone() throws CloneNotSupportedException;
public interface Serializale() //标识接口,能被序列化
序列化:把一个标准要想让对象具有拷贝的功能,必须实现cloneable接口(标识接口,表示此类允许被clone),并且在类中自定义clone调用object类提供的继承权限clone方法
//实现拷贝处理
student = (Student)super.clone();
1.浅拷贝:对象值拷贝
对于浅拷贝而言,拷贝出来的对象仍然保留原对象的所有引用。
问题:牵一发而动全身
只要拷贝对象(或原对象)中任意一个的引用发生改变,所有对象均会受到影响
2.深拷贝:
深拷贝,拷贝出来的对象产生了所有引用的新的对象
特点:修改任意一个对象,不会对其他对象产生影响
如何实现深拷贝:
1.包含的其他类继续实现clonebale接口,并且调用clone方法(递归实现克隆)
import java.io.*;
/**
* Created with IntelliJ IDEA
*
* @Description: cloneable实现深拷贝
* @Author: zhen
* @Date: 2019/8/15
* @Time: 20:28
*/
class Teacher1 implements Serializable {
private String name;
private Integer age;
public Teacher1(String name,Integer age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public Integer age(){
return age;
}
public void setName(){
this.name = name;
}
public void setAge(){
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//实现Cloneable接口
class Student1 implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public Student1(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
public Student1 clone(){
Student1 stu = null;
try {
//调用super的clone方法
stu = (Student1) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public String toString(){
return "Student{"+"name="+name+"age="+age+"}";
}
}
public class CloneableTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Teacher teacher = new Teacher("a",12);
Student1 student = new Student1("b",33,teacher);
Student1 studentClone = student.clone();
}
}
问题:如果继承的类比较多的话,每个类都得实现cloneable接口,工作量比较大。
2.序列化(*****)
优点:使用序列化进行深拷贝时,无须再实现Cloneable接口,只需要实现Serializable即可。
import java.io.*;
/**
* Created with IntelliJ IDEA
*
* @Description: 通过序列化实现克隆
* @Author: zhen
* @Date: 2019/8/15
* @Time: 20:11
*/
class Teacher implements Serializable{
private String name;
private Integer age;
public Teacher(String name,Integer age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public Integer age(){
return age;
}
public void setName(){
this.name = name;
}
public void setAge(){
this.age = age;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Student implements Serializable {
private String name;
private int age;
private Teacher teacher;
public Student(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
public Student cloneObject() throws IOException, ClassNotFoundException {
//序列化方式实现clone方法
//通过内存进行序列化的读取与写入
//1.获取内存流
ByteOutputStream bos = new ByteOutputStream();
//2.获取序列化的两个核心类
ObjectOutputStream oos = new ObjectOutputStream(bos);
//3.把当前对象写入内存中
oos.writeObject(this);
//反序列化取出值
ByteArrayInputStream bis = new ByteArrayInputStream(bos.getBytes());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Student)ois.readObject();
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public String toString(){
return "Student{"+"name="+name+",age="+age+"}";
}
}
public class Cloneserliz {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Teacher teacher = new Teacher("a",12);
Student student = new Student("b",33,teacher);
Student studentClone = student.cloneObject();
System.out.println(student);
System.out.println(studentClone);
System.out.println(studentClone.getName());
System.out.println(studentClone.getAge());
System.out.println(studentClone.getTeacher().getName());
System.out.println(teacher == studentClone.getTeacher());
}
}