java基础-浅复制与深复制的理解
浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢?
要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制。复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等。我们可以发现,复制操作后可以得到两份相同的东西,即复制由一变为二了。下面来看一个例子:
public class User{
private int age;
public int getAge(){
return age;
}
}
User user1 = new User();
User user2 = user1;
上面把user2 = user1属于复制吗?显然,这种操作不属于复制,因为user2=user1仅仅是把user1的引用赋值给user2,此时user1与user2指向内存中同一个对象,所以没有一变成二。在Java中的复制需要得到两个相同的对象,而不是指两个相同的引用。
如果要得到一个真正的复制对象,需要自行实现clone()方法,clone()方法存在于Object类中,默认被所有的类继承,方法签名如下:
protected native Object clone() throws CloneNotSupportedException;
由于clone()方法是用protected修饰的,不能在类外被调用,所以我们如果要复制一个对象,就需要在类中覆盖clone()方法,并把修饰符升级为public,而且被复制的类需要实现Cloneable接口,否则调用clone()方法时会抛出CloneNotSupportedException异常。
public class User implements Cloneable{
public User(int age){
this.age = age;
}
private int age;
public int getAge(){
return age;
}
public Object clone() {
User user = null;
try{
user = super.clone();
}catch(Exception e){
}
return user;
}
}
User usr1 = new User();
User usr2 = usr1.clone();
System.out.println(usr1==usr2);
System.out.println(usr1.getAge()+", "+ usr2.getAge());
######结果
false
,
说明clone方法得到了两个对象,且变量相同。上面的例子说明的仅仅是浅复制的情况,下面再来看一个例子:
public class Phone{
private String name;
public Phone(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
public class User implements Cloneable{
public User(int age){
this.age = age;
this.phone = new Phone("华为");
}
private int age;
public Phone phone;
public int getAge(){
return age;
}
public Object clone() {
User user = null;
try{
user = super.clone();
}catch(Exception e){
}
return user;
}
}
上面代码定义了User类和Phone类,其中User类有一个Phone类的变量,下面调用这两个类:
User usr1 = new User();
User usr2 = usr1.clone();
System.out.println(usr1==usr2);
System.out.println(usr1.getAge()+", "+ usr2.getAge());
System.out.println(usr1.phone.getName()+", "+ usr2.phone.getName());
usr1.phone.setName("小米");
System.out.println(usr1.phone.getName()+", "+ usr2.phone.getName());
###结果
false
,
华为, 华为
小米, 小米
有没有发现一些问题了?修改usr1的变量phone的name的值,修改为“小米”,但是usr2的变量phone的name的值也变为“小米”了。这说明了usr1与usr2的phone变量引用的Phone对象是同一个的,上面的这种复制就是浅复制,浅复制没有复制引用类型的变量。
为了达到深复制,我们需要把类中的引用类型也变成可复制化,即实现Cloneable接口,如下:
public class Phone implements Cloneable{
private String name;
public Phone(String name){
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public Object clone(){
Phone phone = null;
try{
phone = super.clone();
}catch(Exception e){
}
return phone;
}
}
public class User implements Cloneable{
public User(int age){
this.age = age;
this.phone = new Phone("华为");
}
private int age;
public Phone phone;
public int getAge(){
return age;
}
public Object clone() {
User user = null;
try{
user = super.clone();
}catch(Exception e){
}
user.phone = (Phone)phone.clone();
return user;
}
}
由上可以总结,浅复制会把基本数据类型的变量都复制一份,对于引用类型变量只是仅仅对引用进行复制,没有对引用的内存对象进行复制;而深复制会把对象复制一份,也会把对象的引用变量指向的对象复制一份,深复制复制更加彻底。
文章同步发布在朗度云网站上,传输门:
http://www.wolfbe.com/detail/201608/271.html
java基础-浅复制与深复制的理解的更多相关文章
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...
- Java里的浅复制与深复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- JAVA中浅复制与深复制
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- Java中的“浅复制”与“深复制”
复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...
- 也来谈一谈js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...
- js的浅复制和深复制
1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...
- php对象复制、clone、浅复制与深复制实例详解
php对象复制.clone.浅复制与深复制实例详解 一.用clone(克隆)来复制对象$obj1 = new Object();$obj2 = clone $obj1;clone方法会触发对象里定义的 ...
- iOS 浅复制和深复制的深层理解,含示例
转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...
随机推荐
- 一款基于jQuery的仿百度首页滑动选项卡
今天给大家分享一款基于jQuery的仿百度首页滑动选项卡.这款选项卡适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
- Joy of Programming: Understanding Bit-fields in C
转:http://www.linuxforu.com/2012/01/joy-of-programming-understanding-bit-fields-c/ By S.G. Ganesh on ...
- NET开发必备工具之-LINQPad
第一步,下载:http://www.linqpad.net/ 第二步,安装 第三步,打开LINQPad 第四步,添加链接 第五步,输入SQL Server,用户名,密码 第六步,点击OK,成功链接 第 ...
- 小白日记47:kali渗透测试之Web渗透-XSS(一)
XSS [推荐书籍:XSS跨站脚本攻击剖析与防御] xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/ ...
- WPF 之 WPF应用程序事件
当新建一个wpf应用程序,会自动生成一个App.xaml和MainWindow.xaml文件. 其中 App.xam 用来设置Application,应用程序的起始文件和资源及应用程序的一些属性和事件 ...
- 在xml文件中写入&符号时需要对其进行转义
如:在xml文件中保存这样的测试文件: <?xml version="1.0" encoding="utf-8"?> <datas> & ...
- 1.6.2 Uploading Data with Index Handlers
1.Uploading Data with Index Handlers 索引处理器就是Request Handlers,用于添加,更新,删除索引中的文档.另外,使用Tika抽取富文档数据,使用Dat ...
- solr查询在solrconfig.xml中的配置
<requestHandler name="/select" class="solr.SearchHandler"> <lst name=&q ...
- 【Linux/Ubuntu学习5】Ubuntu 下android 开发,eclipse不能识别手机
ubuntu下eclipse不能识别手机解决方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1) 在终端运行 lsusb 会发现结果 ...
- leetcode 题解: Length of Last Word
leetcode: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', re ...