java面试基础 -- 深克隆 浅克隆

引例

        说到java的克隆你还记得多少? 一说到克隆你可能就会想起来那个接口, 没错, 他就是Cloneable

        Cloneable是java里面内置的很常用的接口, 我们说 Object类中也有一个clone方法:

         但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常.

         于是, 我们创建一个类为Dog类, 如下:

public class Main {public static void main(String[] args) throws CloneNotSupportedException {Dog dog1 = new Dog();Dog dog2 = (Dog) dog1.clone();System.out.println(dog1 == dog2);}
}class Dog implements Cloneable {public String dogName;public int dogAge;@Overrideprotected Object clone() throws CloneNotSupportedException {Dog newDog = null;newDog = (Dog) super.clone();return newDog;}
}

输出结果:




深克隆 vs 浅克隆

        浅克隆只复制对象本身和对象的本数据类型字段,而不复制引用类型字段所指向的对象.
这里的引用类型, 可以是类的引用, 也可以是字符串等.

        我们说实现了Cloneable接口的类拷贝出来的对象是浅拷贝还是深拷贝??? 

案例:

public class Main {public static void main(String[] args) throws CloneNotSupportedException {Animal animal1 = new Animal();Animal animal2 = (Animal) animal1.clone();animal2.classIn = 2;animal2.dog.name = "小白";System.out.println(animal1.toString());System.out.println(animal2.toString());}
}class Dog {String name = "小黑";
}
class Animal implements Cloneable {public Dog dog = new Dog();public int classIn = 1;@Overridepublic String toString() {return "Animal{" +"dogName=" + dog.name +", classIn=" + classIn +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

输出结果:

        可以看出来, 他们里面的类的实例却是共享的, 里面的类的引用不同, 但是引用的是同一个类对象. 这就是浅拷贝. 




如何深克隆

深克隆:基本数据类型变量和引用类型变量指向的对象都会被复制,即针对引用类型的成员变量真正的复制一份,重新开辟空间保存,这样两个引用类型属性互不影响。

        那么如何进行深拷贝呢??

         很容易想到的一点就是, 在重写object中的clone方法, 然后对被克隆的类里面的类引用继续克隆. 也就是嵌套克隆

public class Main {public static void main(String[] args) throws CloneNotSupportedException {Animal animal1 = new Animal();Animal animal2 = (Animal) animal1.clone();animal2.classIn = 2;animal2.dog.name = "小白";System.out.println(animal1.toString());System.out.println(animal2.toString());}
}class Dog implements Cloneable{String name = "小黑";@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
class Animal implements Cloneable {public Dog dog = new Dog();public int classIn = 1;@Overridepublic String toString() {return "Animal{" +"dogName=" + dog.name +", classIn=" + classIn +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {Animal newAnimal = (Animal) super.clone();newAnimal.dog = (Dog) dog.clone();return  newAnimal;}
}

输出结果:




总结

  • 在Java中,克隆操作可以分为浅克隆和深克隆两种方式。浅克隆只复制对象本身和对象的本数据类型字段,而不复制引用类型字段所指向的对象。深克隆则会复制对象本身以及对象的引用类型字段所指向的对象,即完全复制了整个对象的所有内容。
  • 浅克隆是通过调用对象的clone()方法来实现的,它会创建一个新的对象,并将原对象的字段值复制到新对象中。但是,新对象和原对象共享同一个引用类型字段对象,所以改变其中一个对象的引用类型字段会影响到另一个对象。
  • 深克隆需要在克隆方法中对引用类型字段进行递归复制。具体实现方法是,在克隆方法中调用引用类型字段的clone()方法来复制该字段所指向的对象。这样就可以创建一个新的对象,并将原对象的所有字段值和引用类型字段所指向的对象的字段值都复制到新对象中,实现了完全独立的克隆。
  • 总结来说,浅克隆只复制对象本身和基本数据类型字段,而深克隆会复制整个对象的所有内容,包括引用类型字段所指向的对象。

引用: :java中的克隆有浅克隆和深克隆之分,造成这种区别是因为java中对于基本数据类型和引用类型类型的存储是不一样的,基本数据类型存储在栈中,而引用数据类型存储在堆中,因此造成了在克隆时的不同操作。 :针对上面的例子只需要在Friend也实现Cloneable接口,并重写clone()方法,然后更改Person中的clone()方法。 :clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足 对任何的对象x,都有x.clone() !=x 因为克隆对象与原对象不是同一个对象对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何下载和安装google字体(中文)

打开:https://fonts.google.com/ 点击字体 下载 解压 双击安装 查看 控制面板-》字体-》

scalacache 配合 guava

代码 package com.yy.guavaimport scalacache._ import scalacache.guava._ import scalacache._ import scalacache.guava._ import com.google.common.cache.CacheBuilder import scalacache.modes.sync._ import scalacache.serialization.binary._ import scalacache._ im…

.net日志系统

.NET 平台提供了强大的日志记录系统,用于在应用程序中记录各种事件、错误和调试信息。最常用的日志记录库是 Microsoft.Extensions.Logging,它是一个通用的日志接口和基础框架,可以与多种日志实现集成。以下是如何使用 .NET 日志系统的基本步骤: 安装 NuGet 包:首先,您需…

大数据课程K1——Spark概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的背景; ⚪ 了解Spark的特点; ⚪ 掌握Spark的生态系统模块、使用模式; ⚪ 掌握Spark的单机模式安装; 一、简介 1. 背景 Spark是UC Berkeley AMP lab (加州大学伯克利分校…

武汉凯迪正大—变比组别测试仪

一、概述 在电力变压器的半成品、成品生产过程中,新安装的变压器投入运行之前以及根据国家电力部的预防性试验规程中,要求变压器进行匝数比或电压比测试。传统的变比电桥操作繁琐,读数不直观,且要进行必要的换算,测试时…

git拉取失败/git fatal终极解决方法

前言 被折磨不下20次总结出来的终极方案 步骤 0 首先关闭代理试试,不行就下一步 1 重置代理或者取消代理的方式 git config --global --unset http.proxy git config --global --unset https.proxy添加全局代理 git config --global http.proxy git config …

Docker容器:Docker-Compose

Docker容器:Docker-Compose 一.Docker-Compose概念 1.Docker-Compose使用场景 一个Dockerfile模板文件可以定义一个单独的应用容器,如果需要定义多个容器就需要服务编排。服务编排有很多种技术方案,今天是介绍 Docker 官方产品 Docker Com…

Java 关键技术汇总-备忘录

java关键点总结: volatile:保证可见性visibility (并不能保证原子性) java线程会缓存变量的值,可能导致缓存值和主内存的值不一致。即缓存一致性问题。Java内存模型规定了所有的变量都存储在主内存中,每条…

python 模块lxml 处理 XML 和 HTML 数据

xpath:https://blog.csdn.net/randy521520/article/details/132432903 一、安装 XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML 文档中对元素和属性进行遍历。 pip install lxml二、使用案例 from lxml impo…

【React】生命周期和钩子函数

概念 组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程。 只有类组件才有生命周期。 分为三个阶段: 挂载阶段更新阶段销毁阶段 三个阶段 挂载阶段 钩子函数 - constructor 创建阶段触发 作用:创建数据 之前定义状态是简写&…

面试题-React(三):什么是JSX?它与常规JavaScript有什么不同?

在React的世界中,JSX是一项引人注目的技术,它允许开发者在JavaScript中嵌套类似HTML的标签,用于描述UI组件的结构。本篇博客将通过丰富的代码示例,深入探索JSX语法,解析其在React中的用法和优势。 一、JSX基础语法 在…

PHP服饰文化网站系统Dreamweaver开发mysql数据库web结构php编程计算机网页项目

一、源码特点 PHP 服饰文化网站系统是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 源码下载 https://download.csdn.net/download/qq_41221322/88236778 PHP服饰文化网站…

两两交换链表中的节点

你存在,我深深的脑海里~ 题目: 示例: 思路: 这个题有点类似于反转一个单链表,不同的地方在于这个题不全反转,所以我们不同的地方在于此题多用了一个prve指针保存n1的前一个节点,以及头的改变&a…

Windows、Mac、Linux端口占用解决

Windows、Mac、Linux端口占用解决 简介 在使用计算机网络时,经常会遇到端口被占用的问题。当一个应用程序尝试使用已经被其他程序占用的端口时,会导致端口冲突,使应用程序无法正常运行。本文将介绍在Windows、Mac和Linux操作系统上解决端口…

写之前的项目关于使用git remote -v 找不到项目地址的解决方案

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、报错解析1. 报错内容2. 报错翻译3. 报错解析(1)使用git branch来查看git仓库有几个分支(2)使用git remote -v&am…

实景无人直播平台是这么开发出来的

标题:实景无人直播平台开发:探索专业性、思考深度与逻辑性的全新体验 随着科技的不断进步,实景无人直播平台成为了当今数字娱乐领域的热门话题。这种新型娱乐方式将虚拟与现实相结合,为用户带来了前所未有的视听体验。本文将探…

Mybatis ORDER BY 排序失效 ORDER BY 与 CASE WHEN THEN 排序问题

一、ORDER BY 排序失效 如果传递给 mapper 的参数值是以 #{test_参数} 的形式&#xff0c;那么就会报错 具体如下&#xff1a; 传递参数是 name 排序规则是升序 asc package com.ruoyi.web.mapper; public interface TestMapper {List<TestEntity> getTestData( Para…

Python学习笔记第五十九天(Matplotlib 安装)

Python学习笔记第五十九天 Matplotlib 安装后记 Matplotlib 安装 本章节&#xff0c;我们使用 pip 工具来安装 Matplotlib 库&#xff0c;如果还未安装该工具&#xff0c;可以参考 Python pip 安装与使用。 如果您还没有安装Matplotlib&#xff0c;您可以按照以下步骤在Pytho…

英飞凌在车辆信息安全方面上应用

如今&#xff0c;网络安全在多个层面影响着我们每个人。我们的专业工作、个人生活&#xff0c;甚至我们的汽车&#xff0c;都依赖于复杂软件上运行的连接和技术。随着信息技术日益融入我们的日常生活&#xff0c;我们对后续信息系统的依赖性也与日俱增。反过来&#xff0c;这些…

【Leetcode】108. 将有序数组转换为二叉搜索树

一、题目 1、题目描述 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例1: 输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-1…