Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的。
下面来看一个关于引用的例子。
package referenceCopy;
// 一个文件中允许有多个类,但是public类型的类只能有一个
class Basic {
private int aInt = 0;
public int getAInt() {
return aInt;
}
public void setAInt(int int1) {
aInt =int1;
}
public void changeInt() {
this.aInt = 1;
}
}
public class Children {
// int char double 等基本类型都是按照值传递的,
// 除此之外的其他类型都是按照引用进行传递的。
public static void main(String[] args) {
// TODO Auto-generated method stub
Basic b = new Basic();
Basic a = b;
b.changeInt();
System.out.println(b.getAInt());
System.out.println(a.getAInt());
}
}
输出的结果为1,1
究其原因是a和b的指向同一个引用。
那么如何变成两个引用呢,我们提出了浅复制和深复制。
首先我们来看浅复制
package referenceCopy;
import java.util.Date;
// 一个文件中允许有多个类,但是public类型的类只能有一个
class BasicA implements Cloneable{
private int aInt = 0;
private Date birth = new Date();
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public void changeBirth() {
this.birth.setMonth(1);
}
public int getAInt() {
return aInt;
}
public void setAInt(int int1) {
aInt =int1;
}
public void changeInt() {
this.aInt = 1;
}
// 改写clone方法
public Object clone() {
Object o = null;
try {
o = (BasicA)super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
public class WeakChildrenReferneceCopy {
// int char double 等基本类型都是按照值传递的,
// 除此之外的其他类型都是按照引用进行传递的。
// 相对于Children类,该类采用了浅复制的方法来进行复制。
// 基本的数据类型变量已经全部复制了进来,但是具体对象的改变并未改变
public static void main(String[] args) {
BasicA b = new BasicA();
BasicA a = (BasicA)b.clone();
b.changeInt();
b.changeBirth();
// 由此可见,浅复制只复制了简单的数据类型,
// 对于复杂的数据类型并未进行复制
System.out.println(a.getAInt());
System.out.println(b.getAInt());
System.out.println(b.getBirth());
System.out.println(a.getBirth());
}
}
输出的结果如下所示:
0
1
Mon Feb 06 14:45:47 CST 2017
Mon Feb 06 14:45:47 CST 2017
由结果可以看出,浅复制并未改变其他对象的引用。
由此,我们提出了深复制
package referenceCopy;
import java.util.Date;
//一个文件中允许有多个类,但是public类型的类只能有一个
class BasicB implements Cloneable{
private int aInt = 0;
private Date birth = new Date();
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public void changeBirth() {
this.birth.setMonth(1);
}
public int getAInt() {
return aInt;
}
public void setAInt(int int1) {
aInt =int1;
}
public void changeInt() {
this.aInt = 1;
}
// 改写clone方法
public Object clone() {
// 强复制需要将返回的复制对象改变为自己需要的对象
BasicB o = null;
try {
o = (BasicB)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
o.birth = (Date)this.getBirth().clone();
return o;
}
}
public class StrongChildrenReferenceCopy {
public static void main(String[] args) {
BasicB a = new BasicB();
BasicB b = (BasicB) a.clone();
b.changeInt();
b.changeBirth();
System.out.println(a.getAInt());
System.out.println(b.getAInt());
System.out.println(a.getBirth());
System.out.println(b.getBirth());
}
}
运行结果如下:
0
1
Thu Jul 06 14:55:13 CST 2017
Mon Feb 06 14:55:13 CST 2017
由上处进行了标红的地方可以看出两者在进行复制时的不同之处。
浅复制:被复制的对象的所有 变量都含有与原来对象相同的值,而所有对其他对象的引用仍然指向原来对象相同的值。换言之,浅复制只复制自己考虑的对象,未复制它所引用的对象。
深复制:被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制的新对象,而不是原有的那些被引用的对象,换言之,深复制把复制对象 所引用的对象都复制了一遍。
Java中引用的浅复制和深复制的更多相关文章
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- JAVA中浅复制与深复制
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- Java中的“浅复制”与“深复制”
复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...
- java基础-浅复制与深复制的理解
浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...
- Java里的浅复制与深复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- 深度解析javascript中的浅复制和深复制
原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...
- js中的浅复制和深复制
浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...
- Python中的浅复制、深复制
参考 https://docs.python.org/3/library/copy.html?highlight=copy%20copy#copy.copy https://en.wikipedia. ...
- php对象复制、clone、浅复制与深复制实例详解
php对象复制.clone.浅复制与深复制实例详解 一.用clone(克隆)来复制对象$obj1 = new Object();$obj2 = clone $obj1;clone方法会触发对象里定义的 ...
随机推荐
- Net分布式系统之六:微服务之API网关
本人建立了个人技术.工作经验的分享微信号,计划后续公众号同步更新分享,比在此更多具体.欢迎有兴趣的同学一起加入相互学习.基于上篇微服务架构分享,今天分享其中一个重要的基础组件“API网关”. 一.引言 ...
- 论MySQL何时使用索引,何时不使用索引
索引: 使用索引可快速访问数据库表中的特定信息.索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓(name)列.如果要按姓查找特定职员,与必须搜索表中的所有行相比,索 ...
- php原生自定义验证码,5分钟搞定你的问题
当然现在很多php的框架里面自带了很多很多验证码,我的这个验证码,也是当初刚刚入行的时候学习模仿的.现在照搬出来,希望对刚入门的朋友有所帮助. **************************** ...
- nodejs 开启debug选项问题
我的机器上设置debug选项是,debug与(等号)=之间不可以有空格,否则设置无效 如下: set DEBUG = * 无打印 set DEBUG=*正常打印
- 如何有效的跟踪线上 MySQL 实例表和权限的变更
介绍 从系统管理员或 DBA 的角度来讲, 总期望将线上的各种变更限制在一个可控的范围内, 减少一些不确定的因素. 这样做有几点好处: . 记录线上的库表变更; . 对线上的库表变更有全局的了解; . ...
- python 2.7中urllib 2 与python 3.5中 urllib的区别。
python 3.x中urllib库和urilib2库合并成了urllib库. 其中urllib2.urlopen()变成了urllib.request.urlopen() urllib2.Reque ...
- Scrapy教程--豆瓣电影图片爬取
一.先上效果 二.安装Scrapy和使用 官方网址:https://scrapy.org/. 安装命令:pip install Scrapy 安装完成,使用默认模板新建一个项目,命令:scrapy s ...
- PHP版本替换, phpinfo和php -v显示版本信息不一致
环境:OS X EI Capitan 10.11 & lnmp 背景: 1想将lamp(xampp安装的,php5.2)换成 lnmp(php7.0) 2php5.2卸载(xampp卸载& ...
- java并发编程(Exchanger)
package org.bianqi.demo1; import java.util.concurrent.Exchanger; import java.util.concurrent.Executo ...
- 浅谈Android studio中OKHttp安装及简单使用
Google貌似在6.0版本里面删除了HttpClient相关API,鉴于okhttp的口碑相当好,介绍一下OKHttp的安装及使用: 一.安装 对于Android Studio的用户,在Projec ...