栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

[JavaSE] Clonable(深克隆,浅克隆)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[JavaSE] Clonable(深克隆,浅克隆)

目录

往期回顾,专栏一览

 Clonable

 对象创建

 调用方法   

 小结:一个对象如何被克隆?

 面试问题

 代码升华!浅拷贝?

 深拷贝实现!


欢迎各路大佬来到 Nick 主页指点


☀️本期文章将学习 [JavaSE] Clonable 克隆,我是博主Nick。✨


✨我的博客主页:Nick_Bears ꧔ꦿ


꧔ꦿ博文内容如对您有所帮助,还请给个点赞 + 关注 + 收藏✨

  

 Clonable

  

 对象创建

 创建对象的几种方式?

  

  1. new
  2. 克隆方法

      

class Person{
    public String name;
    public Money money = new Money();

    public void play() {
        System.out.println("敲代码");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=" + name +
                '}';
    }

public class Demo {
    public static void main(String[] args) {
        Person person = new Person();
        Person person1 = person.clone();
    }
}

   

 我们发现 clone() 是爆红的,我们查看  clone() 的源码试试

   

 于是改成

Person person1 = (Person)person.clone();

  

 恶心的是仍然报错!!!通过学习,我们知道一个对象实现 clone 说明该对象是可克隆的!于是在被克隆类上实现 Cloneable 接口。

class Person implements Cloneable{
    public int age;

    public void play(){
        System.out.println("玩!");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }
    

    //快捷键:Ctrl + O
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

     

     

 我们发现 clone() 还是爆红的,那么我们抛一下异常

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        //并且抛出异常即可
        Person person1 = (Person) person.clone();
    }
}

   

 调用方法   

  思考:person 默认继承 Object,为什么通过引用不能调用克隆方法?

   

 答:可以调用,只是 clone 比较特殊,只是我们必须要重写。

   

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

      

 我们已经调用了 clone() 方法,他会帮我们做什么事情?产生一个副本!

  

 小结:一个对象如何被克隆?
  • 必须实现 Cloneable 接口
  • 重写 Object 的 clone() 方法
  • 调用方法抛异常

   

 输出克隆的对象

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.age = 99;
        Person person1 = (Person) person.clone();
        System.out.println(person1);
    }
}

//输出
Person{age=99}

   

 修改克隆对象的值,查看克隆值和原来的值

public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.age = 99;
        Person person1 = (Person) person.clone();
        System.out.println(person1);

        System.out.println("====================");
        person1.age=199;
        System.out.println(person);
        System.out.println(person1);
    }
}

//输出
Person{age=99}
====================
Person{age=99}
Person{age=199}

  

 上面这个代码是深拷贝吗?

   

答:决定是 深拷贝 还是 浅拷贝 不是某一个方法的使用,或者对应哪种数据类型,而是代码的实现,就是你的代码是如何写的,处理过程如何!我只能说在这种情况下这是深拷贝。

   

 面试问题
  • 思考:你知道Clonable接口吗?
  • 思考:为啥这接口是个空接口?
  • 思考:有啥作用?

   

答:空接口->标志接口->代表当前类可以被克隆。

     

 代码升华!浅拷贝?

 我给 Person 新增了一个 Money 属性

class Money{
    public double m = 13.14;
}
class Person implements Cloneable{
    public int age;
    public Money money = new Money();

    public void play(){
        System.out.println("玩!");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
    }

   

     

 我们通过图推测下面的代码运行都是13.14

   

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
        System.out.println("================");
    }
//结果
13.14
13.14
================

      

 那么我们现在来改掉一个值,可想而知都是同一个引用

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
        System.out.println("================");
        person1.money.m = 1314;
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
    }
//结果
13.14
13.14
================
1314.0
1314.0

 对于目前情况来说,这是一个浅拷贝,那么我们如何实现深拷贝呢?我们是不是应该也把 Money 复制一份呢?

        

 深拷贝实现!

 我们在上面代码的基础上添加一些代码,对 Money 也连接克隆接口,并且重写

class Money implements Cloneable {
    public double m = 13.14;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

   

 这样以后我们就能对 Money 也拷贝一份(在 Person 的方法中)

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person)super.clone();
        //把钱也拷贝一份
        tmp.money = (Money)this.money.clone();
        //return super.clone();
        return tmp;
    }

      

     

 此时我们再次测试刚刚的方法

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
        System.out.println("================");
        person1.money.m = 1314;
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
    }
//运行结果
13.14
13.14
================
13.14
1314.0

      

 代码一览
package 接口.常用接口.Clonable;

class Money implements Cloneable{
    public double m = 10000;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable {
    public String name;
    public Money money = new Money();

    public void play() {
        System.out.println("玩王者");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=" + name +
                '}';
    }

    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp =(Person)super.clone();
        tmp.money = (Money) this.money.clone();
//        return super.clone();
        return tmp;
    }
}


public class Demo {

    
    public static void main1(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.name = "Nick";
        Person person1 = (Person) person.clone();
        System.out.println(person1);

        System.out.println("============================");
        person1.name = "Nicks";
        System.out.println(person1);
        System.out.println(person);
//执行结果
//        Person{name=Nick}
//============================
//        Person{name=Nicks}
//        Person{name=Nick}
    }

    
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        Person person1 = (Person) person.clone();
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
        System.out.println("===============================");
        person1.money.m = 999999;
        System.out.println(person.money.m);
        System.out.println(person1.money.m);
//运行结果(重写接口前)
//        10000.0
//        10000.0
//        ==============================
//        999999.0
//        999999.0
    }

//运行结果(重写接口后)
//        10000.0
//        10000.0
//        ===============================
//        10000.0
//        999999.0
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/983553.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号