Java复制 Java随笔记

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战


相关文章

Java随笔记:随笔记


前言

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

一、直接赋值

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

二、浅拷贝

  • 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typescript复制代码class Resume implements Cloneable {
       public Object clone() {
           try {
               return (Resume) super.clone();
          } catch (Exception e) {
               e.printStackTrace();
               return null;
          }
      }
    }
  • 自己可以实现Cloneable接口。点进去看下这个super.clone();是啥玩意。

  • image-20211103193352225.png

  • 原来用的是native方法。

+ native方法大家都知道,这玩意不是java写的,只是供Java调用而已。
+ 因为Java程序是运行在JVM虚拟机上面的,要想访问到比较底层的与操作系统相关的就没办法了,只能由靠近操作系统的语言来实现。
  • 因为每个类直接或间接的父类都是Object,因此它们都含有clone()方法,但是因为该方法是protected,所以都不能在类外进行访问。
  • 要想对一个对象进行复制,就需要对clone方法覆盖

三、深拷贝

  • 深拷贝不仅复制对象本身,而且复制对象包含的引用指向的所有对象。
  • 如果我们一个对象里面的属性是另一个对象怎么办?
+ 
1
2
3
4
5
6
arduino复制代码@Data
public class teacher {
   private String name;
   private int age;
   private Student student;
}
+
1
2
3
4
5
java复制代码@Data
class Student implements Cloneable {
   private String name;
   private int age;
}
  • 这种情况下如何进行复制?其实通过重写clone()方法也可以做到深度克隆,但是较麻烦。在此不做介绍。
  • 通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
+ 序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。
+ 通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象。
+ 因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    java复制代码@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();
      }
    }
  • 1
    2
    3
    4
    5
    6
    less复制代码@Data
    @AllArgsConstructor
    public class Student implements Serializable {
       private String name;
       private int age;
    }
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    java复制代码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();
          }
      }
    }
  • 执行结果:

+ ![image-20211103195458492.png](https://gitee.com/songjianzaina/juejin_p17/raw/master/img/eb56f15a084f88db0ae427366ff8ea98aa7bcdd3e1dd427972f6dbb9ed9a408f)

路漫漫其修远兮,吾必将上下求索~

如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧~hahah

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%