• ​Cloneable接口


    作者~小明学编程 

    文章专栏JavaSE基础

    格言目之所及皆为回忆,心之所想皆为过往
    在这里插入图片描述

    目录

    Cloneable接口

    浅拷贝

    深拷贝


    Cloneable接口

    Java 中内置了一些很有用的接口, Clonable 就是其中之一,Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。

    下面给大家一个实例:

    浅拷贝

    定义:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

    1. class Person implements Cloneable{
    2. public int age;
    3. public void eat() {
    4. System.out.println("eat()");
    5. }
    6. @Override
    7. public String toString() {
    8. return "Person{" +
    9. "age=" + age +
    10. '}';
    11. }
    12. @Override
    13. protected Object clone() throws CloneNotSupportedException {
    14. return super.clone();
    15. }
    16. }
    17. public class TestDome {
    18. public static void main(String[] args) throws CloneNotSupportedException {
    19. Person person = new Person();
    20. person.age = 100;
    21. Person person2 = (Person) person.clone();
    22. System.out.println(person2);
    23. }
    24. }

    这里我们是通过实现接口进行了一个浅拷贝。

    1. public static void main(String[] args) throws CloneNotSupportedException {
    2. Person person = new Person();
    3. person.age = 100;
    4. Person person2 = (Person) person.clone();
    5. person2.age = 10;
    6. System.out.println(person);
    7. System.out.println(person2);
    8. }

    我们这里对person2的age进行一个更改然后我们接着输出person和person2我们看到结果。

     深拷贝

    定义:深拷贝是一个整个独立的对象拷贝,深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

    1. class Money {
    2. public int m = 88;
    3. }
    4. class Person implements Cloneable{
    5. public int age;
    6. public Money money = new Money();
    7. public void eat() {
    8. System.out.println("eat()");
    9. }
    10. @Override
    11. public String toString() {
    12. return "Person{" +
    13. "age=" + age +
    14. '}';
    15. }
    16. @Override
    17. protected Object clone() throws CloneNotSupportedException {
    18. return super.clone();
    19. }
    20. }
    21. public class TestDome {
    22. public static void main(String[] args) throws CloneNotSupportedException {
    23. Person person = new Person();
    24. Person person2 = (Person) person.clone();
    25. System.out.println(person.money.m);
    26. System.out.println(person2.money.m);
    27. System.out.println("----------------------");
    28. person2.money.m = 99;
    29. System.out.println(person.money.m);
    30. System.out.println(person2.money.m);
    31. }
    32. }

     这里我们看到我们打印的都是99,这是因为啥呢,我们前面所进行的拷贝只是单纯的一个拷贝,不会拷贝我们对象里面的对象所以我们person和person2都是公用同一个Money类的,要想解决这个问题我们就得对对象里面的对象也进行拷贝,这里就叫做我们的深拷贝。

    1. class Money implements Cloneable{
    2. public int m = 88;
    3. @Override
    4. protected Object clone() throws CloneNotSupportedException {
    5. return super.clone();
    6. }
    7. }
    8. class Person implements Cloneable{
    9. public int age;
    10. public Money money = new Money();
    11. public void eat() {
    12. System.out.println("eat()");
    13. }
    14. @Override
    15. public String toString() {
    16. return "Person{" +
    17. "age=" + age +
    18. '}';
    19. }
    20. @Override
    21. protected Object clone() throws CloneNotSupportedException {
    22. Person tem = (Person) super.clone();
    23. tem.money = (Money) this.money.clone();
    24. return tem;
    25. }
    26. }
    27. public class TestDome {
    28. public static void main(String[] args) throws CloneNotSupportedException {
    29. Person person = new Person();
    30. Person person2 = (Person) person.clone();
    31. System.out.println(person.money.m);
    32. System.out.println(person2.money.m);
    33. System.out.println("----------------------");
    34. person2.money.m = 99;
    35. System.out.println(person.money.m);
    36. System.out.println(person2.money.m);
    37. }
    38. }

    首先我们的Money类要实现一个cloneable的接口才能对我们当前的类进行一个拷贝,之后就是重写我们的clone方法.

    1. protected Object clone() throws CloneNotSupportedException {
    2. Person tem = (Person) super.clone();
    3. tem.money = (Money) this.money.clone();
    4. return tem;
    5. }

    首先定义一个临时的变量tem,并且将super.clone()强转为Person之后找到我们对象里面的Money对象再进行一个强转操作,最后进行返回。

     这里我们就实现了深拷贝。

  • 相关阅读:
    分享篇:最近在研究的AIGC内容
    Android Native 开发 要点记录
    Sql注入(手工注入思路、绕过、防御)
    k8s-19 资源限制与监控
    使用HTML制作静态网站作业——我的校园运动会(HTML+CSS)
    taobao.logistics.dummy.send( 无需物流发货处理 )接口,淘宝r2接口,淘宝oAu2.0接口,淘宝订单发货接口
    Json转bean-【下划线和陀螺峰格式互转】
    学历不高、起点低的人,如何逆袭人生?
    【Python】深入解析Python中的eval()函数
    Java--日志管理
  • 原文地址:https://blog.csdn.net/m0_56911284/article/details/127130688