java Clone接口和深拷贝详解

 更新时间:2021年08月24日 10:57:39   作者:eaglewgs  
今天小编就为大家分享一篇关于Java Clonable接口和深拷贝详解上的深入了解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

对于数组的拷贝,如果是简单类型的话是深拷贝,如果是引用类型的话是浅拷贝,但是因为java是面向对象的,在回答面试官问题的时候,我们可以不用说的这么细,可以直接说浅拷贝。

代码示例1

class Person implements Cloneable{//如果想克隆自定义类,那么需要在自定义类上实现Cloneable接口
    public int age;
    /*疑问:为什么这个接口是空接口呢?这是一个面试问题。
    空节课:也把它叫做标记接口。其实就是这个意思:只要一个类实现了这个接口,那么就标记这个类是可以进行clone的
    *
    * 2:重写clone方法*/
    @Override
    protected Object clone() throws CloneNotSupportedException {//重写了父类的克隆方法
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.age);
        System.out.println(person2.age);
        System.out.println("=======修改=======");
        person2.age = 99;
        System.out.println(person1.age);
        System.out.println(person2.age);
    }
    /*public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        int[] array2 = array.clone();//对这个数组进行克隆
        array2[0] = 33;//改变拷贝后的数组元素的值不会影响原来数组的元素,这种情况是深拷贝
        System.out.println(Arrays.toString(array2));
        System.out.println(Arrays.toString(array));
    }*/
}

输出为:

在这里插入图片描述

因为改变的是简单类型,所以这种情况是深拷贝。

代码示例2

class Money{
    double money = 12.5;
}
class Person implements Cloneable{//如果想克隆自定义类,那么需要在自定义类上实现Cloneable接口
    public int age;
    /*疑问:为什么这个接口是空接口呢?这是一个面试问题。
    空节课:也把它叫做标记接口。其实就是这个意思:只要一个类实现了这个接口,那么就标记这个类是可以进行clone的
    *
    * 2:重写clone方法*/
    Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {//重写了父类的克隆方法
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========修改==========");
        person2.m.money = 99.9;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

输出为:

在这里插入图片描述

可以参考以下图分析:

在这里插入图片描述

这种情况就是浅拷贝,那么可以将这个浅拷贝变成深拷贝吗?只需要将Money也克隆一下

class Money implements Cloneable{//如果想要变成深拷贝的话,那么money也需要被克隆。
    double money = 12.5;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{//如果想克隆自定义类,那么需要在自定义类上实现Cloneable接口
    public int age;
    Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {//重写了父类的克隆方法
        Person p = (Person)super.clone();//1:将当前的对象克隆一份,克隆person
        p.m = (Money) this.m.clone();//2:克隆当前的Money对象
        return p;
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========修改==========");
        person2.m.money = 99.9;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

在这里插入图片描述

这样就就将浅拷贝转变成了深拷贝,可以参考以下图分析:

在这里插入图片描述

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • spring中时间格式化的两种方法示例讲解

    spring中时间格式化的两种方法示例讲解

    这篇文章主要介绍了spring中时间格式化的两种方法,方法一自己格式化,方法二通过配置,结合实例代码讲解的非常详细,文中补充介绍了Spring项目中时间格式化的方法,需要的朋友可以参考下
    2023-08-08
  • Mybatis Interceptor线程安全引发的bug问题

    Mybatis Interceptor线程安全引发的bug问题

    这篇文章主要介绍了Mybatis Interceptor线程安全引发的bug问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • SpringBoot基于Mybatis-Plus自动代码生成

    SpringBoot基于Mybatis-Plus自动代码生成

    这篇文章主要介绍了SpringBoot基于Mybatis-Plus自动代码生成,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 关于Https协议和HttpClient的实现详解

    关于Https协议和HttpClient的实现详解

    这篇文章主要给大家介绍了关于Https协议和HttpClient实现的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • 使用feign客户端传参接收不到的问题及解决

    使用feign客户端传参接收不到的问题及解决

    这篇文章主要介绍了使用feign客户端传参接收不到的问题及解决,具有很好的参考价值,希望对大家有所帮助。
    2022-03-03
  • IntelliJ IDEA 使用经验总结(推荐)

    IntelliJ IDEA 使用经验总结(推荐)

    这篇文章主要介绍了IntelliJ IDEA 使用经验总结,非常不错,具有参考价值,需要的朋友可以参考下
    2018-02-02
  • web中拖拽排序和java后台交互实现方法示例

    web中拖拽排序和java后台交互实现方法示例

    这篇文章主要给大家介绍了关于web中拖拽排序和java后台交互实现的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • SpringBoot扫描不到Controller的解决方案

    SpringBoot扫描不到Controller的解决方案

    这篇文章主要介绍了SpringBoot扫描不到Controller的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • nacos配置中心远程调用读取不到配置文件的解决

    nacos配置中心远程调用读取不到配置文件的解决

    这篇文章主要介绍了nacos配置中心远程调用读取不到配置文件的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。
    2022-01-01
  • MyBatis工厂类封装与简化实现

    MyBatis工厂类封装与简化实现

    工厂类的目的是将对象的创建逻辑封装在一个类中,以便客户端代码无需了解具体的实现细节,本文主要介绍了MyBatis工厂类封装与简化实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01

最新评论