IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java克隆 -> 正文阅读

[Java知识库]java克隆

什么是克隆

java的克隆类似于对象的复制。

为什么需要克隆

想对一个对象进行处理,且保留原有的对象。
比如根据一个叫张三的学生信息,复制出李四、王五的学生信息,且保留张三的学生信息,然后组装三个学生的List。

java克隆分类

java克隆分为浅克隆与深克隆。

  1. 浅克隆:只克隆基本类型。引用类型没有克隆,只是新建一个引用,该引用仍然指向原有的对象。比如张三的学生信息中,有老师这个引用对象。克隆张三的学生信息修改成李四的信息后,老师信息并未被克隆,修改张三的老师,李四的老师也被修改。
  2. 深克隆:基本类型和引用类型都被克隆,引用类型的变量指向的是新克隆的对象。

下面上代码实例,为了保险起见,咱们上三层嵌套。Student里有Teacher,Teacher里有Course。

浅克隆

  1. Student代码
package org.ludk.clone;

/**
 * @author ludengke
 * @title: Student
 * @projectName springcloud-demo
 * @description: TODO
 * @date 2021/10/1822:13
 */
public class Student implements Cloneable{
    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 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;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", teacher=" + teacher +
                '}';
    }
}

  1. Teacher代码
package org.ludk.clone;

/**
 * @author ludengke
 * @title: Teacher
 * @projectName springcloud-demo
 * @description: TODO
 * @date 2021/10/1822:14
 */
public class Teacher implements Cloneable{
    private String name;
    private int age;
    private Course course;

    public Teacher(String name, int age, Course course) {
        this.name = name;
        this.age = age;
        this.course = course;
    }

    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 Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

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

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", course=" + course +
                '}';
    }
}


  1. Course代码
package org.ludk.clone;

/**
 * @author ludengke
 * @title: Course
 * @projectName springcloud-demo
 * @description: TODO
 * @date 2021/10/1822:15
 */
public class Course {
    private String name;
    private int days;

    public Course(String name, int days) {
        this.name = name;
        this.days = days;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

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

    @Override
    public String toString() {
        return "Course{" +
                "name='" + name + '\'' +
                ", days=" + days +
                '}';
    }
}


  1. 测试类代码
package org.ludk.clone;

/**
 * @author ludengke
 * @title: TestClone
 * @projectName springcloud-demo
 * @description: 克隆学习测试类
 * @date 2021/10/1719:12
 */
public class TestClone implements Cloneable{
    /**
     * main方法
     * @param args
     */
    public static void main(String[] args) throws CloneNotSupportedException {
        //新建个学生张三
        Student student=new Student("张三",24,new Teacher("王老师",40,new Course("英语",90)));
        //克隆学生
        Student cloneStudent=(Student) student.clone();
        System.out.println("学生张三和克隆学生是否为一个老师");
        System.out.println(student.getTeacher()==cloneStudent.getTeacher());
        System.out.println("学生张三和克隆学生是否为一个课程");
        System.out.println(student.getTeacher().getCourse()==cloneStudent.getTeacher().getCourse());
        System.out.println("学生张三的信息");
        System.out.println(student);
        //克隆学生的信息
        System.out.println("克隆学生的信息");
        System.out.println(cloneStudent);
    }
}


  1. 测试类执行结果
D:\work\java\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=62957:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\work\java\jre\lib\charsets.jar;D:\work\java\jre\lib\deploy.jar;D:\work\java\jre\lib\ext\access-bridge-64.jar;D:\work\java\jre\lib\ext\cldrdata.jar;D:\work\java\jre\lib\ext\dnsns.jar;D:\work\java\jre\lib\ext\jaccess.jar;D:\work\java\jre\lib\ext\jfxrt.jar;D:\work\java\jre\lib\ext\localedata.jar;D:\work\java\jre\lib\ext\nashorn.jar;D:\work\java\jre\lib\ext\sunec.jar;D:\work\java\jre\lib\ext\sunjce_provider.jar;D:\work\java\jre\lib\ext\sunmscapi.jar;D:\work\java\jre\lib\ext\sunpkcs11.jar;D:\work\java\jre\lib\ext\zipfs.jar;D:\work\java\jre\lib\javaws.jar;D:\work\java\jre\lib\jce.jar;D:\work\java\jre\lib\jfr.jar;D:\work\java\jre\lib\jfxswt.jar;D:\work\java\jre\lib\jsse.jar;D:\work\java\jre\lib\management-agent.jar;D:\work\java\jre\lib\plugin.jar;D:\work\java\jre\lib\resources.jar;D:\work\java\jre\lib\rt.jar;D:\work\springcloud-demo\target\classes org.ludk.clone.TestClone
学生张三和克隆学生是否为一个老师
true
学生张三的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}
克隆学生的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}

Process finished with exit code 0


从上面的例子,可以看到学生信息被复制了,但是里面的Teacher信息仍然是一个,仍然是一个对象。

深克隆

深克隆有两种方法。一种是遇到属性为引用类型,则对该引用类型对象进行复制。另一种是用序列化实现深克隆。

第一种方法性能高些,但是实现起来复杂,因为对象里可能还嵌套对象。第二种方法实现起来简单,但是性能差些。

自定义深克隆

  1. 修改Student的clone方法
@Override
    protected Object clone() throws CloneNotSupportedException {
        Student cloneStudent= (Student)super.clone();
        cloneStudent.setTeacher((Teacher) this.getTeacher().clone());
        return cloneStudent;
    }
  1. 再次跑测试类的结果
D:\work\java\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=50882:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\work\java\jre\lib\charsets.jar;D:\work\java\jre\lib\deploy.jar;D:\work\java\jre\lib\ext\access-bridge-64.jar;D:\work\java\jre\lib\ext\cldrdata.jar;D:\work\java\jre\lib\ext\dnsns.jar;D:\work\java\jre\lib\ext\jaccess.jar;D:\work\java\jre\lib\ext\jfxrt.jar;D:\work\java\jre\lib\ext\localedata.jar;D:\work\java\jre\lib\ext\nashorn.jar;D:\work\java\jre\lib\ext\sunec.jar;D:\work\java\jre\lib\ext\sunjce_provider.jar;D:\work\java\jre\lib\ext\sunmscapi.jar;D:\work\java\jre\lib\ext\sunpkcs11.jar;D:\work\java\jre\lib\ext\zipfs.jar;D:\work\java\jre\lib\javaws.jar;D:\work\java\jre\lib\jce.jar;D:\work\java\jre\lib\jfr.jar;D:\work\java\jre\lib\jfxswt.jar;D:\work\java\jre\lib\jsse.jar;D:\work\java\jre\lib\management-agent.jar;D:\work\java\jre\lib\plugin.jar;D:\work\java\jre\lib\resources.jar;D:\work\java\jre\lib\rt.jar;D:\work\springcloud-demo\target\classes org.ludk.clone.TestClone
学生张三和克隆学生是否为一个老师
false
学生张三的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}
克隆学生的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}

Process finished with exit code 0

其实上面的自定义深克隆方法只是深克隆了老师的信息,课程的信息依然为浅克隆。可以自己实现,继续扩展。

java序列化实现深克隆

  1. Teacer、Student、Course都得实现java.io.Serializable接口
  2. 修改Student的clone方法
 @Override
    protected Object clone() throws CloneNotSupportedException {
        Student cloneObj = null;
        try {
            // 写入字节流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new ObjectOutputStream(out);
            obs.writeObject(this);
            obs.close();
            // 分配内存,写入原始对象,生成新对象
            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            // 返回生成的新对象
            cloneObj = (Student) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
  1. 重新跑测试类的结果
D:\work\java\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=55660:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\work\java\jre\lib\charsets.jar;D:\work\java\jre\lib\deploy.jar;D:\work\java\jre\lib\ext\access-bridge-64.jar;D:\work\java\jre\lib\ext\cldrdata.jar;D:\work\java\jre\lib\ext\dnsns.jar;D:\work\java\jre\lib\ext\jaccess.jar;D:\work\java\jre\lib\ext\jfxrt.jar;D:\work\java\jre\lib\ext\localedata.jar;D:\work\java\jre\lib\ext\nashorn.jar;D:\work\java\jre\lib\ext\sunec.jar;D:\work\java\jre\lib\ext\sunjce_provider.jar;D:\work\java\jre\lib\ext\sunmscapi.jar;D:\work\java\jre\lib\ext\sunpkcs11.jar;D:\work\java\jre\lib\ext\zipfs.jar;D:\work\java\jre\lib\javaws.jar;D:\work\java\jre\lib\jce.jar;D:\work\java\jre\lib\jfr.jar;D:\work\java\jre\lib\jfxswt.jar;D:\work\java\jre\lib\jsse.jar;D:\work\java\jre\lib\management-agent.jar;D:\work\java\jre\lib\plugin.jar;D:\work\java\jre\lib\resources.jar;D:\work\java\jre\lib\rt.jar;D:\work\springcloud-demo\target\classes org.ludk.clone.TestClone
学生张三和克隆学生是否为一个老师
false
学生张三和克隆学生是否为一个课程
false
学生张三的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}
克隆学生的信息
Student{name='张三', age=24, teacher=Teacher{name='王老师', age=40, course=Course{name='英语', days=90}}}

Process finished with exit code 0

从上面的例子可以看到,java序列化实现深克隆,那是真的深克隆。

参考

下面是引用https://www.cnblogs.com/xzwblog/p/7230788.html博客的图片

  • 浅克隆

在这里插入图片描述

  • 深克隆
    在这里插入图片描述
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-19 11:44:20  更:2021-10-19 11:46:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:16:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码