一.JAVA假克隆

Java中,对于基本类型,可以用“=”进行克隆,而对于引用类型却不能简单的使用“=”进行克隆,这与JAVA的内存使用空间有关,JAVA在栈中保存基本类型和引用变量,在堆中保存对象。对于引用变量而言,使用“=”将修改引用,而不是复制堆中的对象,此时两个引用对象将指向同一个对象,因此如果对一个变量修改则会修改另一个对象。

public class Employee {
private String name;
private int age;
//省略get和set方法
@Override
public String toString() {
return "姓名:" + name + ", 年龄:" + age;
}
}
public class Test {
public static void main(String[] args) {
System.out.println("克隆之前:");
Employee employee1 = new Employee();
employee1.setName("芋头1");
employee1.setAge(12);
System.out.println("员工1的信息:");
System.out.println(employee1);
System.out.println("克隆之后:");
Employee employee2 = employee1;
employee2.setName("芋头2");
employee2.setAge(114);
System.out.println("员工2的信息:");
System.out.println(employee2);
System.out.println("员工1的信息:");
System.out.println(employee1);
}
}

输出:
克隆之前:
员工1的信息:
姓名:芋头1, 年龄:12
克隆之后:
员工2的信息:
姓名:芋头2, 年龄:114
员工1的信息:
姓名:芋头2, 年龄:114
可以看出,employee1和employ2两个引用变量同时指向一个对象,当修改employee2的域时,employee11的域也被修改,因此是假克隆。
二、浅克隆
protect Object clone() 
通常需要改写该方法并把访问权限限定为public,该方法对于类中的每个域,如果只包含基本类型和不可变的引用类型,如string,或者对象在其生命周期内不可变化,则可以用浅克隆来复制对象。

 public class Address {
private String state;
private String province;
private String city;
//省略get和set
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("国家:" + state + ", ");
sb.append("省:" + province + ", ");
sb.append("市:" + city);
return sb.toString();
}
} public class Employee implements Cloneable {
private String name;
private int age;
private Address address;
//省略get和set
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("姓名:" + name + ", ");
sb.append("年龄:" + age + "\n");
sb.append("地址:" + address);
return sb.toString();
} @Override
public Employee clone() {
Employee employee = null;
try {
employee = (Employee) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return employee;
}
} public class Test {
public static void main(String[] args) {
System.out.println("克隆之前:");
Address address = new Address("中国", "吉林", "长春");
Employee employee1 = new Employee("明日科技", 12, address);
System.out.println("员工1的信息:");
System.out.println(employee1);
System.out.println("克隆之后:");
Employee employee2 = employee1.clone();
employee2.getAddress().setState("中国");
employee2.getAddress().setProvince("四川");
employee2.getAddress().setCity("成都");
employee2.setName("西南交通大学");
employee2.setAge(114);
System.out.println("员工2的信息:");
System.out.println(employee2);
System.out.println("员工1的信息:");
System.out.println(employee1);
}
}

输出:

克隆之前:
员工1的信息:
姓名:明日科技, 年龄:12
地址:国家:中国, 省:吉林, 市:长春
克隆之后:
员工2的信息:
姓名:西南交通大学, 年龄:114
地址:国家:中国, 省:四川, 市:成都
员工1的信息:
姓名:明日科技, 年龄:12
地址:国家:中国, 省:四川, 市:成都

我们发现,employee类中又包含了Adress类adress的引用,我们知道,clone方法默认的是浅克隆,即不会克隆对象引用的对象,而只是简单地复制这个引用。所以在上例中,adress对象在内存中只有一个,employee1和employee2都指向它,任何一个对象对它的修改都会影响另一个对象。所以adress的值也被修改了。
三,深克隆

一种就是在引用类型中添加克隆方法。如对上面的浅克隆代码改成:

在Adress类中增加

protected Address clone() {
Address address = null;
try {
address = (Address) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return address;
}

Employee中:

public Employee clone() {

Employee employee = null;

try {

employee = (Employee) super.clone();

employee.address = address.clone();

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

输出:
克隆之前:
员工1的信息:
姓名:明日科技, 年龄:12
地址:国家:中国, 省:吉林, 市:长春
克隆之后:
员工2的信息:
姓名:西南交通大学, 年龄:114
地址:国家:中国, 省:四川, 市:成都
员工1的信息:
姓名:明日科技, 年龄:12
地址:国家:中国, 省:吉林, 市:长春

实现了深克隆

一个方法自然是重写clone方法,添加如order.items=(LineItems)items.clone()的语句,也就是人为地添加对引用对象的复制。这个方法的缺点是如果引用对象有很多,或者说引用套引用很多重,那么太麻烦了。业界常用的方法是使用串行化然后反串行化的方法来实现深克隆。由于串行化后,对象写到流中,所有引用的对象都包含进来了,所以反串行化后,对等于生成了一个完全克隆的对象。
这个方法的要求是对象(包括被引用对象)必须事先了Serializable接口,否则就要用transient关键字将其排除在复制过程中。

JAVA之路_假克隆、浅克隆、深克隆的更多相关文章

  1. java 浅克隆 深克隆

    对象的克隆是java的一项高级技术,他可以根据给定的对象,获得与其完全相同的另一个对象. 1.浅克隆主要是复制对象的值 2.深克隆:当类存在聚合关系的时候,克隆就必须考虑聚合对象的克隆,可以复制引用类 ...

  2. Java——对象的复制、克隆、序列化

    原创作者: https://blog.csdn.net/lmb55/article/details/78277878对象克隆(复制)假如说你想复制一个简单变量.很简单: int apples = 5; ...

  3. java 浅拷贝和深拷贝 对象克隆clone

    分一下几点讨论: 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 一:为什么要克隆? 大家先思考一个问题,为什么需要克隆对象?直接new一个对象不行吗? 答案是:克隆的对象可能包 ...

  4. Java之路——敬JAVA初学者(作者:MoMo)

    作为一名大四的毕业生,大学三年过,有得有失.作为一个喜欢编程,喜欢JAVA的人,自学其实是一件美事,很有意思的事.要是能再找个女朋友一起学.嘿嘿,就不枉在大学走了一遭啊!    要离开学校了,还是想留 ...

  5. java画图程序_图片用字母画出来_源码发布_版本二

    在上一个版本:java画图程序_图片用字母画出来_源码发布 基础上,增加了图片同比例缩放,使得大像素图片可以很好地显示画在Notepad++中. 项目结构: 运行效果1: 原图:http://imag ...

  6. java画图程序_图片用字母画出来_源码发布

    在之前写了一篇blog:java画图程序_图片用字母画出来 主要是把一些调试的截图发布出来,现在程序调试我认为可以了(当然,你如果还想调试的话,也可以下载源码自己调试). 就把源码发布出来. 项目结构 ...

  7. java画图程序_图片用字母画出来

    最近在研究怎样将图片用字母在文本编辑工具中“画”出来. 你看了这个可能还不知道我想说什么? 我想直接上图,大家一定就知道了 第一张:小猫 原图:http://www.cnblogs.com/hongt ...

  8. Java之路——名词解释(一)

    一.开篇 许多人在初接触Java的时候,都会被各种Java的英文缩写名词给弄得头晕脑胀.看一个技术,内容里又会有一堆其他的技术名词,看了半天不知所云.尝试去查一下这些名词的解释,除了非常学术性的解释之 ...

  9. Java之路——环境配置与编译运行

    本文大纲 一.开篇 二.JDK下载 三.JDK安装 四.环境配置 五.初识Java编译 六.Java与Javac 七.第一个Java程序 八.总结 九.参考资料 一.开篇 通过对之前Java之路的了解 ...

随机推荐

  1. html 05-HTML标签图文详解(二)

    05-HTML标签图文详解(二) #本文主要内容 列表标签:<ul>.<ol>.<dl> 表格标签:<table> 框架标签及内嵌框架<ifram ...

  2. html 01-认识Web和Web标准

    01-认识Web和Web标准 #Web.网页.浏览器 #Web Web(World Wide Web)即全球广域网,也称为万维网. 我们常说的Web端就是网页端. #网页 网页是构成网站的基本元素.网 ...

  3. CVE-2019-2618任意文件上传漏洞复现

    CVE-2019-2618任意文件上传漏洞复现 漏洞介绍: 近期在内网扫描出不少CVE-2019-2618漏洞,需要复测,自己先搭个环境测试,复现下利用过程,该漏洞主要是利用了WebLogic组件中的 ...

  4. C++webservice接口调用

    一.WebService例子 1.准备要调用的webservice接口的wsdl地址,比如网上的查询天气接口:http://ws.webxml.com.cn/WebServices/WeatherWS ...

  5. 流程控制之☞ while 和 for 的故事

    学习三连鞭... 什么是循环? 为什么要有循环? 如何用循环? 循环的基本语法:while   和     for 先来看while循环: while条件:首先得是个循环体. 1.如果条件为真,那么循 ...

  6. Python十大装B语法!你会几种?

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python ...

  7. 数据库SQL调优的几种方式 EFcore读的情况下使用 AsNoTracking非跟踪查询

    不要用GUID 当主键 没有规律 可以用雪花ID DBA 优化法则 硬件资源是根本,DBA是为了充分利用硬件资源 一般清空下可以不使用外键 可以提高性能 合理使用临时表 临时表分页; 一些查询语句加w ...

  8. [每日一题]ES6中为什么要使用Symbol?

    关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...

  9. 两千星 .NET5 框架 Furion 亮点分析(一)

    让 .NET 开发更简单,更通用,更流行. Furion 介绍 Furion 是基于 .NET5 平台下打造的现代化 Web 框架.旨在 让 .NET 开发更简单,更通用,更流行.. Furion 非 ...

  10. 5个有趣且不必要的 JavaScipt 技巧

    前一段时间,我创建了一个标题为"7个可爱的Web开发技巧"的帖子.在这里,我描述了一些有趣的技巧,您可以使用3种主要的Web技术之一来实现这些技巧-html,css和JavaScr ...