当前位置: 首页 > news >正文

Java 深复制和浅复制

  浅复制是指复制对象时仅仅复制对象本身(包括对象中的基本变量),而不复制对象包含的引用指向的对象。深复制不仅复制对象本身,而且复制对象包含的引用指向的对象。

  复制对象时需要调用Object类的clone方法:

1 protected native Object clone() throws CloneNotSupportedException;

  步骤:

  1 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法时会抛出CloneNotSupportedException异常) 。而该接口为标记接口(不含任何抽象方法)。

  2 重写clone()方法,访问修饰符设为public,通过调用super.clone()方法得到需要的复制对象。

  

  浅复制

 1 class Address  {
 2     private String add;
 3 
 4     public String getAdd() {
 5         return add;
 6     }
 7 
 8     public void setAdd(String add) {
 9         this.add = add;
10     }
11     
12 }
13 
14 class Student implements Cloneable{
15     private int number;
16 
17     private Address addr;
18     
19     public Address getAddr() {
20         return addr;
21     }
22 
23     public void setAddr(Address addr) {
24         this.addr = addr;
25     }
26 
27     public int getNumber() {
28         return number;
29     }
30 
31     public void setNumber(int number) {
32         this.number = number;
33     }
34     
35     @Override
36     public Object clone() {
37         Student stu = null;
38         try{
39             stu = (Student)super.clone();
40         }catch(CloneNotSupportedException e) {
41             e.printStackTrace();
42         }
43         return stu;
44     }
45 }
46 public class Test {
47     
48     public static void main(String args[]) {
49         
50         Address addr = new Address();
51         addr.setAdd("杭州市");
52         Student stu1 = new Student();
53         stu1.setNumber(123);
54         stu1.setAddr(addr);
55         
56         Student stu2 = (Student)stu1.clone();
57         
58         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
59         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
60 
61         addr.setAdd("西湖区");
62         
63         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
64         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
65     }
66 }

  结果如下:

1 学生1:123,地址:杭州市  
2 学生2:123,地址:杭州市
3 学生1:123,地址:杭州市  
4 学生2:123,地址:杭州市  
5 学生1:123,地址:西湖区  
6 学生2:123,地址:西湖区

  两个学生的地址都改变了。原因是浅复制只是复制了addr变量的引用,并没有真正地开辟另一块空间来存储地址对象。

  

  深复制

 1 class Address implements Cloneable {
 2     private String add;
 3 
 4     public String getAdd() {
 5         return add;
 6     }
 7 
 8     public void setAdd(String add) {
 9         this.add = add;
10     }
11     
12     @Override
13     public Object clone() {
14         Address addr = null;
15         try{
16             addr = (Address)super.clone();
17         }catch(CloneNotSupportedException e) {
18             e.printStackTrace();
19         }
20         return addr;
21     }
22 }
23 
24 class Student implements Cloneable{
25     private int number;
26 
27     private Address addr;
28     
29     public Address getAddr() {
30         return addr;
31     }
32 
33     public void setAddr(Address addr) {
34         this.addr = addr;
35     }
36 
37     public int getNumber() {
38         return number;
39     }
40 
41     public void setNumber(int number) {
42         this.number = number;
43     }
44     
45     @Override
46     public Object clone() {
47         Student stu = null;
48         try{
49             stu = (Student)super.clone();    //浅复制
50         }catch(CloneNotSupportedException e) {
51             e.printStackTrace();
52         }
53         stu.addr = (Address)addr.clone();    //深度复制
54         return stu;
55     }
56 }
57 public class Test {
58     
59     public static void main(String args[]) {
60         
61         Address addr = new Address();
62         addr.setAdd("杭州市");
63         Student stu1 = new Student();
64         stu1.setNumber(123);
65         stu1.setAddr(addr);
66         
67         Student stu2 = (Student)stu1.clone();
68         
69         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
70         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
71         
72         addr.setAdd("西湖区");
73         
74         System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
75         System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
76     }
77 }

  结果如下:

1 学生1:123,地址:杭州市
2 学生2:123,地址:杭州市
3 学生1:123,地址:西湖区
4 学生2:123,地址:杭州市

  

  参考资料

  java.util.ArrayList.clone是不是彻底的克隆

  Java如何复制对象

转载于:https://www.cnblogs.com/WJQ2017/p/7601784.html

相关文章:

  • 【highlight.js】页面代码高亮插件
  • mxnet的训练过程——从python到C++
  • Nengo 神经网络
  • Linux正则和grep命令
  • Azure 中 Linux 虚拟机的大小
  • 【bzoj1758】[Wc2010]重建计划
  • ros 如何使用 openni2_launch
  • Git应用实践(二)
  • 软件项目管理第2次作业:豆瓣测评
  • 【个人训练】(POJ1276)Cash Machine
  • [转] logback 常用配置详解(序)logback 简介
  • 网络视频监控与人脸识别
  • 混合和过度绘制(图层性能 15.3)
  • 【u235】背单词
  • [置顶] 九月半集训总结
  • Angular 响应式表单之下拉框
  • Angular6错误 Service: No provider for Renderer2
  • classpath对获取配置文件的影响
  • Docker下部署自己的LNMP工作环境
  • Java到底能干嘛?
  • Java深入 - 深入理解Java集合
  • Mysql优化
  • PHP的类修饰符与访问修饰符
  • vue数据传递--我有特殊的实现技巧
  • 不上全站https的网站你们就等着被恶心死吧
  • 如何实现 font-size 的响应式
  • 使用Swoole加速Laravel(正式环境中)
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​Python 3 新特性:类型注解
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1)(1.11) SiK Radio v2(一)
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (js)循环条件满足时终止循环
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (强烈推荐)移动端音视频从零到上手(上)
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .FileZilla的使用和主动模式被动模式介绍
  • .net Application的目录
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .Net 中Partitioner static与dynamic的性能对比
  • .net和php怎么连接,php和apache之间如何连接
  • .ui文件相关
  • /var/lib/dpkg/lock 锁定问题
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [1204 寻找子串位置] 解题报告
  • [asp.net core]project.json(2)
  • [BT]BUUCTF刷题第9天(3.27)
  • [excel与dict] python 读取excel内容并放入字典、将字典内容写入 excel文件
  • [Gamma]阶段测试报告
  • [GDOUCTF 2023]<ez_ze> SSTI 过滤数字 大括号{等
  • [HNCTF 2022 WEEK2]easy_include 文件包含遇上nginx