首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java复制 | Java随笔记

Java复制 | Java随笔记

作者头像
玖柒的小窝
修改2021-11-04 09:47:04
修改2021-11-04 09:47:04
3750
举报
文章被收录于专栏:各类技术文章~各类技术文章~

前言

  • 将一个对象的引用复制给另外一个对象,一共有三种方式。
    • 直接赋值
    • 浅拷贝
    • 深拷贝
    • 这三种概念实际上都是为了拷贝对象
  • 那么这三种拷贝的区别是什么?

一、直接赋值

  • 在 Java 中,A a1 = a2,我们需要理解的是这实际上复制的是引用,也就是说 a1 和 a2 指向的是同一个对象。因此,当 a1 变化的时候,a2 里面的成员变量也会跟着变化。
  • 感觉这个没啥好说的。。不做案例分析。

二、浅拷贝

  • 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。
  • class Resume implements Cloneable {    public Object clone() {        try {            return (Resume) super.clone();       } catch (Exception e) {            e.printStackTrace();            return null;       }   } } 复制代码
  • 自己可以实现Cloneable接口。点进去看下这个super.clone();是啥玩意。
  • 原来用的是native方法。
    • native方法大家都知道,这玩意不是java写的,只是供Java调用而已。
    • 因为Java程序是运行在JVM虚拟机上面的,要想访问到比较底层的与操作系统相关的就没办法了,只能由靠近操作系统的语言来实现。
  • 因为每个类直接或间接的父类都是Object,因此它们都含有clone()方法,但是因为该方法是protected,所以都不能在类外进行访问。
  • 要想对一个对象进行复制,就需要对clone方法覆盖

三、深拷贝

  • 深拷贝不仅复制对象本身,而且复制对象包含的引用指向的所有对象。
  • 如果我们一个对象里面的属性是另一个对象怎么办?
    • @Data public class teacher {    private String name;    private int age;    private Student student; } 复制代码
    • @Data class Student implements Cloneable {    private String name;    private int age; } 复制代码
  • 这种情况下如何进行复制?其实通过重写clone()方法也可以做到深度克隆,但是较麻烦。在此不做介绍。
  • 通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
    • 序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。
    • 通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象。
    • 因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。
  • @Data public class Teacher implements Serializable {    private String name;    private int age;    private Student student; ​    public Teacher(String name, int age, Student student) {        this.name = name;        this.age = age;        this.student = student;   } ​    // 深克隆    public Object deepClone() throws IOException, ClassNotFoundException {        // 序列化        ByteArrayOutputStream bos = new ByteArrayOutputStream();        ObjectOutputStream oos = new ObjectOutputStream(bos);        oos.writeObject(this);        // 反序列化        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());        ObjectInputStream ois = new ObjectInputStream(bis);        return ois.readObject();   } } 复制代码
  • @Data @AllArgsConstructor public class Student implements Serializable {    private String name;    private int age; } 复制代码
  • public class test {    public static void main(String[] args) {        try {            Student s = new Student("大鱼", 24);            Teacher origin = new Teacher("丁老师", 32, s);            System.out.println("克隆前的学生姓名:" + origin.getStudent().getName());            Teacher clone = (Teacher) origin.deepClone();            // 更改克隆后的d学生信息 更改了姓名            clone.getStudent().setName("我是克隆对象更改后的大鱼2");            System.out.println("克隆后的学生姓名:" + clone.getStudent().getName());       }catch (Exception e){            e.printStackTrace();       }   } } 复制代码
  • 执行结果:

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、直接赋值
  • 二、浅拷贝
  • 三、深拷贝
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档