你真的懂Java中的Cloneable接口和深拷贝么?

Cloneable接口 和 深拷贝

文章导读

这篇文章就为大家讲讲什么是Cloneable接口,接口的用法以及什么是深拷贝和浅拷贝,如果有不足的地方,还望读者在评论区提出!!!

上篇文章讲过用Comparable接口进行对象比较,和一个Comparator比较,但是许多有趣的接口还有好多,请让我持续给您讲解,假如,你写了一个重要的代码,但是很害怕万一万一数据丢了怎么办?这时,就有人说了,我直接复制存储一份不就行了么,对,没错,是这样的,现在就要讲一个和复制功能一样的有趣接口:

Cloneable接口

下面,我会根据下面的代码来对Cloneable接口进行讲解:

public class Student implements Cloneable{//实现接口
     int age = 10;
    //重写clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student();
        Student student2 = (Student)student1.clone();
        System.out.println(student1.toString());
        System.out.println(student2.toString());
    }
}

下面将针对上面的代码一段一段的讲解,请拿好你的小板凳认真坐好啦!!!

下面一段一段的代码可能与上面有一点点的不同,那是因为上面是处理过后的完美代码,下面讲解的代码是没有经过处理的,根据没有处理过的代码一步一步带你学会clone()方法,最后就会称为完美的代码!!!

你真的懂Java中的Cloneable接口和深拷贝么?_第1张图片

可以看到,当调用clone()方法时,结果报出了一个异常表示不支持克隆;下面就解决这第一个异常(第一个异常说明这里不止一个异常);

我们点击去clone()方法,看看它的是如何实现的;

在这里插入图片描述

可以看到,clone方法是属于object类的,但是object类不是所有类的父类么,那Student类也应该是Object类的子类呀,在子类中调用父类中的方法,为什么没办法调用呢?

第一个异常:

想要在子类中调用父类的方法,就要通过super进行调用,那么就通过在子类中重写父类的方法,调用重写的clone方法;
你真的懂Java中的Cloneable接口和深拷贝么?_第2张图片

当重写这个方法后发现,它还是报错的,那怎么回事呢?来接着看!

你真的懂Java中的Cloneable接口和深拷贝么?_第3张图片

当把鼠标放在红线位置时发现,有一个添加异常到方法签名,下面就点击一下,发现这个红线不仅没消失还变长了,然后在main方法后添加了一行这个东西,这个异常将在Java异常文章中进行讲解,这里简单提一下,这里表示,在main函数中可能会抛出一个异常,而这个异常如果在方法这里不进行处理的话,就会交给方法的调用者处理,就这样一直向上推,最后交给了jvm进行处理,jvm就会报出错误,终止程序;

你真的懂Java中的Cloneable接口和深拷贝么?_第4张图片

那这个异常是怎么回事呢?是因为:当student1调用clone方法时,因为clone方法的返回类型是Object类型的,而Object类是Student的父类,把父类对象赋值给子类进行了向下转型,所以要进行强制类型转化;

你真的懂Java中的Cloneable接口和深拷贝么?_第5张图片

看,这样就没有红线啦,那么现在就运行起来!!!

你真的懂Java中的Cloneable接口和深拷贝么?_第6张图片

结果运行时还报异常,我就想要拷贝一下还没完没了了是吧,不要着急,解决完这个异常,就完事了,可以看到这里表示的是Student不能被拷贝,那么是因为我们还要去实现Cloneable接口;
你真的懂Java中的Cloneable接口和深拷贝么?_第7张图片

当实现完Cloneable接口后,进入这个接口发现,这个接口是空的,那么这个接口有什么用呢?因为啊,这个接口也叫作标记接口,表示这个对象可以被克隆,如果不实现这个对象的话,就没办法进行克隆,没办法,谁让人家就是这么规定的呢

那么 下面就可以正常运行了

你真的懂Java中的Cloneable接口和深拷贝么?_第8张图片

以上就是clone方法的使用,你学废了么!!!
不要打瞌睡,下面就要上硬货啦,既然学过了拷贝,那么就来拓展一下什么是深拷贝吧!!!

深拷贝

下面是完美的代码,没有错误的,下面如果我讲的代码如果有什么不一样的,不要奇怪,那是因为我要给你讲呀!最后都会再回到下面的代码中的。我会一步一步的将下面的代码进行讲解:

class Grade implements Cloneable{
    int grade = 60;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Student implements Cloneable{
     int age = 10;
     Grade g;

     public Student() {
         this.g = new Grade();
     }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student tmp = (Student) super.clone();
        tmp.g = (Grade) this.g.clone();
        return tmp;
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student();
        Student student2 = (Student) student1.clone();
        System.out.println(student1.toString());
        System.out.println(student2.toString());
        System.out.println("===========================");
        //对student2中g的grade进行修改
        student2.g.grade = 90;
        System.out.println(student1.g.grade);
        System.out.println(student2.g.grade);
    }
}

请看我慢慢给你讲解:

你真的懂Java中的Cloneable接口和深拷贝么?_第9张图片

然而结果并不理想,它把两个对象里的grade都改了,哎!我不是进行了拷贝么,怎么会改一个把两个全都改了呢?上面之所以是这种情况是因为,现在并没有构成深拷贝,而是下图这种情况,请看下面图解:

你真的懂Java中的Cloneable接口和深拷贝么?_第10张图片

它只是对Student对象中的内容进行了一份拷贝,但是并没有对,对象中的对象中的内容进行拷贝也就是grade=60;这种情况就是浅拷贝!那想要进行深拷贝该怎么操作呢?下面请看我讲解:
你真的懂Java中的Cloneable接口和深拷贝么?_第11张图片

以上就是讲解,下面将根据上面的讲解做的一个配图;
你真的懂Java中的Cloneable接口和深拷贝么?_第12张图片

就仅仅对clone方法里面的代码添加了三行就构成了深拷贝,所以是不是很神奇呢!!!

你真的懂Java中的Cloneable接口和深拷贝么?_第13张图片

你可能感兴趣的:(#,JavaSE语法,java,开发语言)