• Java的Object类和深拷贝和浅拷贝(面试题)


    1.java.lang.Object类的说明

    • 1.Object类是所有Java类的根父类

    • 2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类

    • 3.Object类中的功能(属性、方法)就具通用性。

    • 属性:无

    • 方法:equals() / toString() / getClass() /hashCode() / clone() / finalize()

      wait() 、 notify()、notifyAll()

      1. Object类只声明了一个空参的构造器

    1.拷贝的引入

    (1)引用拷贝

    创建一个指向对象的引用变量的拷贝。

    Teacher teacher = new Teacher("Taylor",26);
    Teacher otherteacher = teacher;
    System.out.println(teacher);
    System.out.println(otherteacher);
    结果:
    blog.Teacher@355da254
    blog.Teacher@355da254
        由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherteacher的只是引用而已,他们都指向了一个相同的对象Teacher(Taylor,26)。 这就叫做引用拷贝。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    (2)对象拷贝

    创建对象本身的一个副本。

    Teacher teacher = new Teacher("Swift",26);
    Teacher otherteacher = (Teacher)teacher.clone();
    System.out.println(teacher);
    System.out.println(otherteacher);
    
    blog.Teacher@355da254
    blog.Teacher@4dc63996
        结果分析:由输出结果可以看出,它们的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量,这就叫做对象拷贝。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    注:深拷贝和浅拷贝都是属于->对象拷贝

    2.浅拷贝

    浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象

         Student student1 = new Student();
          student1.setName("Dream");
          student1.setAge(18);
          student1.setTeacher(teacher);//student1引用的teacher对象
    
            Student student2 = (Student) student1.clone();
    //student2仅仅复制了student1对象,不复制student1引用的teacher对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    两个引用student1和student2指向不同的两个对象,但是两个引用student1和student2中的两个teacher引用指向的是同一个对象,所以说明是浅拷贝。

    对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。"里面的对象“会在原来的对象和它的副本之间共享

    在这里插入图片描述

    3.深拷贝

    简而言之,深拷贝把要复制的对象所引用的对象都复制了一遍。深拷贝相比于浅拷贝速度较慢并且花销较大。

         	Teacher3 t = new Teacher3();
            t.setName("Delacey");
            t.setAge(29);
    //深拷贝后:Teacher作为2个对象的引用对象 输出name
    		t.setName("Jam"); 
    //只有student1指向对象的引用Teacher对象改了  因为student1和2指向两个对象的引用对象Teacher并不是同一个地址了。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    两种方式实现深拷贝:

    1:不常用

     	    Teacher3 t = new Teacher3();
            t.setName("Taylor");
            t.setAge(28);
    
    		Student3 student1 = new Student3();
            student1.setName("Dream");
            student1.setAge(18);
            student1.setTeacher(teacher);
    
            Student3 student2 = (Student3) student1.clone();
    ---------------
          @Override
        public Object clone() throws CloneNotSupportedException {
            // 浅复制时:
            // Object object = super.clone();
            // return object;
    
            // 改为深复制:
            Student3 student = (Student3) super.clone();
            // 本来是浅复制,现在将Teacher对象复制一份并重新set进来
            student.setTeacher((Teacher2) student.getTeacher().clone());
            return student;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2:利用序列化实现深拷贝

        	Teacher3 t = new Teacher3();
            t.setName("Taylor");
            t.setAge(28);	
    
    		Student3 s1 = new Student3();
            s1.setAge(20);
            s1.setName("blank space");
            s1.setTeacher(t);
    
            Student3 s2 = (Student3) s1.deepClone();
    
    ------------------------------------------------
       public Object deepClone() throws Exception {
            // 序列化
            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
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    mysql倒序查询
    一行代码,让 VS Code 内置 PDF 阅读器变成深色模式
    打造千万级流量秒杀第十一课 系统参数:如何按业务场景优化网络性能?
    文字的力量
    前端面试官必备-面试宝典HTML与CSS
    山东大学开发可解释深度学习算法 RetroExplainer,4 步识别有机物的逆合成路线
    [OC学习笔记]属性关键字
    国际物流和跨境电商物流的区别
    双向带头循环链表的(增删查改)的是实现
    ClickHouse常用函数速查大全
  • 原文地址:https://blog.csdn.net/dougongzi/article/details/131089581