cloneable接口

Cloneable 接口是 Java 标准库中的一个标记接口,用于指示一个类的对象能够被合法地克隆。克隆是指创建一个对象的副本,即一个新的对象,其内容与原对象相同。Cloneable 接口本身没有方法,它只是一个标记,表示实现这个接口的类支持克隆操作。

Cloneable 接口的用途

Cloneable 接口的主要用途是与 Object 类中的 clone() 方法配合使用:

  1. 表示类支持克隆

    • 如果一个类实现了 Cloneable 接口,那么表示该类的对象可以被克隆。
    • clone() 方法在调用时会检查对象是否实现了 Cloneable 接口。如果没有实现,则会抛出 CloneNotSupportedException 异常。
  2. 支持浅克隆

    • Object 类的 clone() 方法通过直接复制对象的字段来实现浅克隆。
    • 如果对象的字段是基本数据类型或不可变对象(如 String),那么浅克隆已经足够。
    • 如果对象的字段是可变对象(如数组或自定义对象),则需要实现深克隆。

Cloneable 接口的实现原理

实现 Cloneable 接口并使用 clone() 方法通常需要以下步骤:

  1. 实现 Cloneable 接口

    • 类需要实现 Cloneable 接口,表示该类支持克隆操作。
  2. 重写 clone() 方法

    • 在类中重写 clone() 方法,并调用 super.clone() 方法来执行实际的克隆操作。
  3. 处理异常

    • clone() 方法需要处理 CloneNotSupportedException 异常。
  4. 可选:实现深克隆

    • 如果需要实现深克隆,需在 clone() 方法中手动克隆可变对象的字段。

示例代码

以下是一个实现 Cloneable 接口并支持克隆操作的简单示例:

class Person implements Cloneable {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 调用 Object 类的 clone() 方法}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}public static void main(String[] args) {try {Person person1 = new Person("Alice", 30);Person person2 = (Person) person1.clone(); // 克隆对象System.out.println(person1);System.out.println(person2);System.out.println("person1 == person2: " + (person1 == person2)); // falseSystem.out.println("person1.equals(person2): " + person1.equals(person2)); // true} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

在这个示例中:

  • Person 类实现了 Cloneable 接口,并重写了 clone() 方法。
  • clone() 方法中调用了 super.clone(),这会调用 Object 类的 clone() 方法,创建一个新的 Person 对象,其字段值与原对象相同。
  • 克隆操作后,person1person2 是两个不同的对象,但它们的内容是相同的。

深克隆示例

如果类中包含可变对象,需要实现深克隆,如下所示:

class Address implements Cloneable {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}@Overridepublic String toString() {return "Address{city='" + city + "'}";}
}class Person implements Cloneable {private String name;private int age;private Address address;public Person(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;}@Overrideprotected Object clone() throws CloneNotSupportedException {Person cloned = (Person) super.clone();cloned.address = (Address) address.clone(); // 深克隆地址return cloned;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + ", address=" + address + "}";}public static void main(String[] args) {try {Address address = new Address("New York");Person person1 = new Person("Alice", 30, address);Person person2 = (Person) person1.clone();System.out.println(person1);System.out.println(person2);person2.address.setCity("San Francisco");System.out.println("After modifying address:");System.out.println(person1);System.out.println(person2);} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

在这个深克隆示例中:

  • Address 类也实现了 Cloneable 接口,并重写了 clone() 方法。
  • Person 类的 clone() 方法中,不仅克隆了 Person 对象本身,还克隆了其包含的 Address 对象,确保 Person 对象的深克隆。

通过实现 Cloneable 接口和重写 clone() 方法,Java 对象可以支持浅克隆或深克隆,根据具体需求灵活处理对象的复制。

深克隆(Deep Copy)和浅克隆(Shallow Copy)是两种不同的对象复制方式。它们的主要区别在于复制的深度,即对于引用类型字段(如对象、数组等)的处理方式不同。

深浅克隆

浅克隆

浅克隆是指创建一个新对象,这个新对象的所有字段都与原对象的字段值相同。但对于引用类型字段,新对象只是复制了引用,而不是引用指向的实际对象。换句话说,浅克隆后的新对象和原对象共享同一个引用对象。

示例

假设有一个 Person 类,包含一个引用类型字段 Address

class Address {private String city;public Address(String city) {this.city = city;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}
}class Person implements Cloneable {private String name;private Address address;public Person(String name, Address address) {this.name = name;this.address = address;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 浅克隆}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic String toString() {return "Person{name='" + name + "', address=" + address.getCity() + "}";}
}

测试浅克隆:

public class ShallowCloneTest {public static void main(String[] args) {try {Address address = new Address("New York");Person person1 = new Person("Alice", address);Person person2 = (Person) person1.clone();System.out.println("Before modification:");System.out.println(person1);System.out.println(person2);person2.getAddress().setCity("San Francisco");System.out.println("After modification:");System.out.println(person1);System.out.println(person2);} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

输出结果:

Before modification:
Person{name='Alice', address=New York}
Person{name='Alice', address=New York}
After modification:
Person{name='Alice', address=San Francisco}
Person{name='Alice', address=San Francisco}

可以看到,修改 person2 的地址会影响 person1,这是因为浅克隆只是复制了引用,两个对象共享同一个 Address 实例。

深克隆

深克隆是指创建一个新对象,这个新对象的所有字段都与原对象的字段值相同。对于引用类型字段,新对象会创建一个新的实例,并复制引用对象的内容。这样,深克隆后的新对象和原对象是完全独立的。

示例

Person 类实现深克隆:

class Person implements Cloneable {private String name;private Address address;public Person(String name, Address address) {this.name = name;this.address = address;}@Overrideprotected Object clone() throws CloneNotSupportedException {Person cloned = (Person) super.clone();cloned.address = new Address(this.address.getCity()); // 深克隆return cloned;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic String toString() {return "Person{name='" + name + "', address=" + address.getCity() + "}";}
}

测试深克隆:

public class DeepCloneTest {public static void main(String[] args) {try {Address address = new Address("New York");Person person1 = new Person("Alice", address);Person person2 = (Person) person1.clone();System.out.println("Before modification:");System.out.println(person1);System.out.println(person2);person2.getAddress().setCity("San Francisco");System.out.println("After modification:");System.out.println(person1);System.out.println(person2);} catch (CloneNotSupportedException e) {e.printStackTrace();}}
}

输出结果:

Before modification:
Person{name='Alice', address=New York}
Person{name='Alice', address=New York}
After modification:
Person{name='Alice', address=New York}
Person{name='Alice', address=San Francisco}

可以看到,修改 person2 的地址不会影响 person1,这是因为深克隆创建了 Address 的新实例,每个 Person 对象有自己的 Address 实例。

总结

  • 浅克隆:复制对象时,只复制原对象的基本类型字段和引用类型字段的引用。克隆对象与原对象共享同一个引用对象。
  • 深克隆:复制对象时,除了复制基本类型字段外,对于引用类型字段,也会创建新的实例并复制其内容。克隆对象与原对象完全独立。

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

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

相关文章

HTML(27)——渐变

渐变是多个颜色逐渐变化的效果,一般用于设置盒子模型 线性渐变 属性:background-image : linear-gradient( 渐变方向 颜色1 终点位置, 颜色2 终点位置, ......); 取值: 渐变方向:可选 to 方位名词角度度数 终点位置:可选 百分…

Java语言+后端+前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码

Java语言后端前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码 Java开发的数字化产科管理系统,已在多家医院实施,支持直接部署。系统涵盖孕产全程,包括门诊、住院、统计和移动服务,整合高危管理、智能提醒、档案追踪等…

idea运行旧的项目如何引入jar包

背景: 有一个旧项目,年份不详, 生产环境运行正常, 生产环境jenkins打包正常;部分jar包为私包,已无法下载 现在要对这个项目进行调试修改 从生产环境下载正常的jar包解压找到lib把lib放到项目目录中 然后选者对应的jdk版本: 一个模块一个模块的 把刚才的库加进去 然后试着启…

Unity海面效果——5、水沫和海平线

Unity引擎制作海面效果 大家好,我是阿赵。 继续做海面效果,上次做完了漫反射颜色和水波动画,还有法线和高光效果。 原则上来说,这个海面已经基本能看了,从性能的考虑,到这里差不多可以停止了。不过有些细节…

error: ‘make_unique’ is not a member of ‘g2o’ 的参考解决方法

文章目录 写在前面一、问题描述二、解决方法 写在前面 自己的测试环境: Ubuntu20.04 一、问题描述 编译调用g2o的程序时,出现如下报错 error: ‘make_unique’ is not a member of ‘g2o’; did you mean ‘std::make_unique’?42 | auto s…

文章SameStr(四):图4代码

“Publication Figure 4” 百度云盘链接: https://pan.baidu.com/s/15g7caZp354zIWktpnWzWhQ 提取码: 4sh7 Libraries Standard Import library(tidyverse) library(cowplot) library(scales) library(ggpubr)Special library(caret) library(plotROC) library(tidymodel…

AIGC:为创意产业注入新质生产力

在当今数字化浪潮下,人工智能(AI)正以惊人的速度重塑着各行各业,特别是在创意产业领域,AI所带来的变革显得尤为深刻且广泛。 我深切感受到AIGC(Artificial Intelligence Generated Content,即人…

几款常见的数字孪生引擎

Unity Unity 是一个通用的游戏引擎,广泛用于创建3D和2D的互动内容。它也被广泛用于数字孪生模型的开发。Unity提供了高效的图形处理能力、物理引擎和跨平台支持,使其成为构建交互式数字孪生模型的理想选择。 ②Unreal Engine Unreal Engine 是另一个流…

淘宝卖家难免遇到的商品问题 在淘宝买的东西出问题了,该如何维权

很多朋友对于淘宝卖家难免遇到的商品问题和在淘宝买的东西出问题了,该如何维权不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧! [1] 淘宝买东西,过了售后期,有质量问题怎…

gen_cross_contour_xld 为每个输入点生成一个十字形状的XLD轮廓。

gen_cross_contour_xld Name 名称 gen_cross_contour_xld — Generate one XLD contour in the shape of a cross for each input point. 为每个输入点生成一个十字形状的XLD轮廓。 Signature 签名 gen_cross_contour_xld( : Cross : Row, Col, Size, Angle : ) Descripti…

uniapp开发android调试工具

程序运行在真机后,点击Hbuilder菜单栏中的视图,点击下方的显示Webview调试控制台 下方就会展示你在手机端操作的界面 点击需要在电脑端调试的界面,界面会在新开的浏览器中展示,这样一些h5浏览器无法点击出来的样式就可以这样调试了…

【Java】搜索引擎设计:信息搜索怎么避免大海捞针?

一、内容分析 我们准备开发一个针对全网内容的搜索引擎,产品名称为“Bingoo”。 Bingoo的主要技术挑战包括: 针对爬虫获取的海量数据,如何高效地进行数据管理;当用户输入搜索词的时候,如何快速查找包含搜索词的网页…

PHP语言教程与实战案例详解

PHP是一种广泛使用的开源脚本语言,尤其适合Web开发并可嵌入HTML中。PHP语法吸收了C语言、Java和Perl的特点,易于学习,使用灵活,支持多种数据库,因此在Web开发领域中占据了重要地位。本文将从PHP的基本概念入手&#xf…

软件测试市场复苏了?

今年大家听到“就业大环境很差”、“工作不好找”之类的太多了。如今大环境已经逐渐好转,虽然不需要太过焦虑,但是也要持续的提升自己。 最近和几位准备跳槽的兄弟聊天发现,原有八股文已经不足以应对现在面试官的提问了。大厂对测试员的技术要…

零基础STM32单片机编程入门(十一) OLED显示屏实战含源码视频

文章目录 一.概要二.0.96寸OLED屏介绍1.OLED屏外观图2.OLED屏特点3.OLED屏接口定义4.OLED屏原理图5.OLED屏像素分辨率 三.字库取模软件PCtoLCD2002介绍四.STM32单片机驱动OLED显示实验五.CubeMX工程源代码下载六.讲解视频链接地址七.小结 一.概要 OLED被称为有机激光二极管显示…

二分查找(红绿标记法)

文章目录 1.线性查找2.二分查找2.1一般的二分查找2.2特殊的二分查找——红绿标记法2.3 原理解释:2.4 代码中的应用: 1.线性查找 线性查找(Linear Search)是一种简单直观的搜索算法,用于在数组中查找特定值的位置。它的…

DBeaver安装教程(开发人员和数据库管理员通用数据库管理工具)

前言 DBeaver 是一个通用的数据库管理工具和 SQL 客户端,支持 MySQL, PostgreSQL, Oracle, DB2, MSSQL, Sybase, Mimer, HSQLDB, Derby, 以及其他兼容 JDBC 的数据库。DBeaver 提供一个图形界面用来查看数据库结构、执行SQL查询和脚本,浏览和导出数据&a…

GEE代码实例教程详解:降水量分类分析

简介 在本篇博客中,我们将使用Google Earth Engine (GEE) 对特定区域内的降水量进行分类分析。通过设定不同的降水量阈值,我们可以将降水量分为干旱、中等和湿润三个类别,并分析这些类别随时间的变化。 背景知识 降水量分类 降水量分类是…

无损音频格式 FLAC 转 MP3 音频图文教程

音频文件的格式多样,每种格式都有其独特的特点与适用场景。FLAC(Free Lossless Audio Codec),作为一种无损音频压缩格式,因其能够完美保留原始音频数据的每一个细节而备受音频发烧友和专业人士的青睐。 然而&#xff0…

NuGet 中国国内镜像

有时候网络不好,需要使用国内的一些镜像源。 华为资源: https://repo.huaweicloud.com/repository/nuget/v3/index.json 腾讯资源: https://mirrors.cloud.tencent.com/nuget/ 微软中国镜像源:https://nuget.cdn.azure.cn/v3…