Java中关于对象的浅克隆以及深克隆详解
这篇文章主要介绍了java 对象的克隆的相关资料,这里对浅克隆和深克隆进行了实例分析需要的朋友可以参考下
java 对象的克隆
一、对象的浅克隆
(1)需要克隆类需要重写Object类的clone方法,并且实现Cloneable接口(标识接口,无需实现任何方法)
(2)当需要克隆的对象中维护着另外一个引用对象,浅克隆不会克隆另外一个引用对下,而是直接复制维护的另外一个引用对象的地址。
(3)对象的浅克隆也不会调用到构造方法。
以下为对象的浅克隆的一个例子:
package com.clone; import java.io.Serializable; /** * Description: * 实现了Cloneable接口,并重写Object类的clone方法。 * * @author lee * */ public class CloneDemo1 implements Cloneable,Serializable{ //该克隆类封装的信息 public int id; public String name; public Address address; /** * Desciption: * 默认构造器 * * */ public CloneDemo1(){} /** * Description: * 初始化id,name的构造器 * * @param id id * @param name 名字 * @param address 地址 * */ public CloneDemo1(int id, String name, Address address){ this.id=id; this.name=name; this.address = address; } /** * Descriptin: * 重写Object类的clone方法。 * if the object's class does not support the Cloneable interface. * Subclasses that override the clone method can also throw this exception * to indicate that an instance cannot be cloned. * * @throws CloneNotSupportedException * */ @Override public Object clone() throws CloneNotSupportedException{ return super.clone(); } /** * Description: * 重写toString方法 * * @return "id="+id+", name="+name * */ @Override public String toString(){ return "id="+id+", name="+name+", address:"+address.getAddress(); } /** * Description: * 主方法 * * */ public static void main(String[] args) throws CloneNotSupportedException{ CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京")); //c2 复制了c1的地址,并没有复制整个c1对象 CloneDemo1 c2 = c1; //c3 对象的浅克隆,复制了整个对象 CloneDemo1 c3 = (CloneDemo1)c1.clone(); //当对象c1改变其name或者id的时候,c2也会自动改变。 //因为c2只是复制了c1的地址,并非复制了c1的整个对象。 //相应的c3则不会随着c1改变而改变,意味着c3将c1整个对象克隆一份出来。 //当是,对象的浅克隆不会克隆被克隆对象当中的引用对象。 //因此c1改变其中的Address的引用对象时,c2,c3也会跟着改变。 c1.setName("cc"); c1.address.setAddress("上海"); System.out.println(c1+"\n"+c2+"\n"+c3); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } /** * Description: * 一个封装着地址的类 * * @author lee * */ class Address implements Serializable{ public String address; /** * Description: * 默认构造器 * * */ public Address(){} /** * Description: * 初试化address * * @param address 地址 * */ public Address(String address){ this.address = address; } //address的set和get方法 public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
二、对象的深克隆
就是利用对象的输入输出流把对象写到文件上,再读取对象的信息,这就是对象的深克隆。
由于对象的浅克隆不会克隆被克隆对象其中的引用对象,而是直接复制其地址。因此,要克隆被克隆对象当中的引用类型则需要对象的深克隆。
而对象的深克隆使用的的对象序列化输入输出。
代码如下:
package com.clone; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * Description: * 实现对象的深克隆 * * @author lee * */ public class CloneDemo2 { /** * Description: * 将对象输出到一个文件当中。 * * @param c 需要被写到文件当中的对象。 * */ public static void writeObject(CloneDemo1 c){ ObjectOutputStream out = null; try{ //将对象输出在一个object.txt文件当中 out = new ObjectOutputStream(new FileOutputStream("./object.txt")); out.writeObject(c); }catch(IOException e){ System.out.println("写入对象的时候发生了错误。"); e.printStackTrace(); }finally{ //关闭资源 try{ out.close(); }catch(IOException e){ e.printStackTrace(); } } } /** * Description: * 从文件中读取出一个对象来,并返回。 * * @return c 返回一个对象。 * */ public static CloneDemo1 readObject(){ CloneDemo1 c = null; ObjectInputStream input = null; try{ //从object.txt文件中读取一个对象出来 input = new ObjectInputStream(new FileInputStream("./object.txt")); c = (CloneDemo1)input.readObject(); }catch(IOException | ClassNotFoundException e){ e.printStackTrace(); System.out.println("读取对象的时候发生了错误。"); }finally{ //关闭资源 try{ input.close(); }catch(IOException e){ e.printStackTrace(); } } return c; } /** * Description: * 主方法 * * @throws CloneNotSupportedException * */ public static void main(String[] args) throws CloneNotSupportedException { CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京")); //c2 对象的浅克隆 CloneDemo1 c2 = (CloneDemo1)c1.clone(); //c3对象的深克隆 writeObject(c1); CloneDemo1 c3 = readObject(); //因为对象的深克隆同时也克隆了被克隆对象维护的另外一个对象 //所以,当c1改变其当中的维护的另外一个对象的时候,c3不会随之改变。 //而c2位浅克隆,其维护的另外一个对象只是复制了c1维护的对象的地址,因此会随着c1的改变而改变。 c1.address.setAddress("上海"); System.out.println(c1+"\n"+c2+"\n"+c3); } }
对象的序列化,是需要实现Serializable接口的。
以上是Java中关于对象的浅克隆以及深克隆详解的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP成为许多网站首选技术栈的原因包括其易用性、强大社区支持和广泛应用。1)易于学习和使用,适合初学者。2)拥有庞大的开发者社区,资源丰富。3)广泛应用于WordPress、Drupal等平台。4)与Web服务器紧密集成,简化开发部署。

PHP适用于Web开发和内容管理系统,Python适合数据科学、机器学习和自动化脚本。1.PHP在构建快速、可扩展的网站和应用程序方面表现出色,常用于WordPress等CMS。2.Python在数据科学和机器学习领域表现卓越,拥有丰富的库如NumPy和TensorFlow。
