Java中的clone方法-理解浅拷贝和深拷贝
最近学到Java虚拟机的相关知识,更加能理解clone方法的机制了
java中的我们常常需要复制的类型有三种:
1:8种基本类型,如int,long,float等;
2:复合数据类型(数组);
3:对象变量。
基本数据类型存放在栈中;而对象实例和数组都在堆上分配。
对于基本数据类型我们不需要考虑浅拷贝和深拷贝,使用等号便可复制值。
对于复合数据类型使用等号浅拷贝,仅复制该字段值,如数组则复制地址。。对复合类型使用clone()方法或者System.arrayCopy进行深拷贝(拷贝复合类型对象的时候,会为其重新创建对象)。
int num1=2;
int num2=num1;
num2=4;
System.out.println(num1==num2);
int[] a={2,1,4,3,5};
int[] b=a;
b[0]=8;
System.out.println(a==b);
int[] c={2,1,4,3,5};
int[] d=c.clone();
d[0]=8;
System.out.println(c==d);
则上述输出为
false true
false
而对于对象变量,使用clone()仅能实现浅拷贝(仅复制对象的在栈中的reference),下面文章具体对对象变量的两种克隆进行分析。
clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。
复制对象 or 复制引用
在Java中,以下类似的代码非常常见:
Person p = new Person(23, "zhang");
Person p1 = p; System.out.println(p);
System.out.println(p1);
com.pansoft.zhangjg.testclone.Person@2f9ee1ac

而下面的代码是真真正正的克隆了一个对象。
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone(); System.out.println(p);
System.out.println(p1);
com.pansoft.zhangjg.testclone.Person@67f1fba0
深拷贝 or 浅拷贝
public class Person implements Cloneable{ private int age ;
private String name; public Person(int age, String name) {
this.age = age;
this.name = name;
} public Person() {} public int getAge() {
return age;
} public String getName() {
return name;
} @Override
protected Object clone() throws CloneNotSupportedException {
return (Person)super.clone();
}
}
Person p = new Person(23, "zhang");
Person p1 = (Person) p.clone(); String result = p.getName() == p1.getName()
? "clone是浅拷贝的" : "clone是深拷贝的"; System.out.println(result);
覆盖Object中的clone方法, 实现深拷贝
static class Body implements Cloneable{
public Head head; public Body() {} public Body(Head head) {this.head = head;} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} }
static class Head /*implements Cloneable*/{
public Face face; public Head() {}
public Head(Face face){this.face = face;} }
public static void main(String[] args) throws CloneNotSupportedException { Body body = new Body(new Head()); Body body1 = (Body) body.clone(); System.out.println("body == body1 : " + (body == body1) ); System.out.println("body.head == body1.head : " + (body.head == body1.head)); }
body.head == body1.head : true
static class Body implements Cloneable{
public Head head;
public Body() {}
public Body(Head head) {this.head = head;} @Override
protected Object clone() throws CloneNotSupportedException {
Body newBody = (Body) super.clone();
newBody.head = (Head) head.clone();
return newBody;
} }
static class Head implements Cloneable{
public Face face; public Head() {}
public Head(Face face){this.face = face;}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException { Body body = new Body(new Head()); Body body1 = (Body) body.clone(); System.out.println("body == body1 : " + (body == body1) ); System.out.println("body.head == body1.head : " + (body.head == body1.head)); }
body.head == body1.head : false
真的是深拷贝吗
static class Body implements Cloneable{
public Head head;
public Body() {}
public Body(Head head) {this.head = head;} @Override
protected Object clone() throws CloneNotSupportedException {
Body newBody = (Body) super.clone();
newBody.head = (Head) head.clone();
return newBody;
} } static class Head implements Cloneable{
public Face face; public Head() {}
public Head(Face face){this.face = face;}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
} static class Face{} public static void main(String[] args) throws CloneNotSupportedException { Body body = new Body(new Head(new Face())); Body body1 = (Body) body.clone(); System.out.println("body == body1 : " + (body == body1) ); System.out.println("body.head == body1.head : " + (body.head == body1.head)); System.out.println("body.head.face == body1.head.face : " + (body.head.face == body1.head.face)); }
body.head == body1.head : false
body.head.face == body1.head.face : true
如何进行彻底的深拷贝
static class Head implements Cloneable{
public Face face; public Head() {}
public Head(Face face){this.face = face;}
@Override
protected Object clone() throws CloneNotSupportedException {
//return super.clone();
Head newHead = (Head) super.clone();
newHead.face = (Face) this.face.clone();
return newHead;
}
} static class Face implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
写在最后
Java中的clone方法-理解浅拷贝和深拷贝的更多相关文章
- 详解Java中的clone方法
详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...
- 详解Java中的clone方法:原型模式
转:http://developer.51cto.com/art/201506/478985.htm clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的 ...
- 转:Java中的Clone()方法详解
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- 详解Java中的clone方法 -- 原型模式
转自: http://blog.csdn.net/zhangjg_blog/article/details/18369201 Java中对象的创建 clone顾名思义就是复制, 在Java语言中, ...
- Java中对Clone的理解
面试中经常遇到Clone的相关知识,今天总算是把Clone理解的比较透彻了!Java中Clone的概念大家应该都很熟悉了,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Cl ...
- java中的clone方法
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- JAVA中的clone方法剖析
原文出自:http://blog.csdn.net/shootyou/article/details/3945221 java中也有这么一个概念,它可以让我们很方便的"制造"出一个 ...
- 深入浅出| java中的clone方法
每天进步一丢丢,连接梦与想 我们还年轻,但这不是你浪费青春的理由 克隆和复制 clone,有人称之为克隆,有人称之为复制,其实都是同一个东西 本文称之为"克隆",毕竟人家方法名叫& ...
- Java中有关clone方法的用法
一.clone在数组基本数据类型中的使用 public class Main { public static void main(String[] args) { int[] arr= {7,8,9} ...
随机推荐
- 30分钟掌握ES6/ES2015核心内容[上和下], 不错的说
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...
- C++学习笔记(2)----类模板和友元
当一个类包含一个友元声明时,类与友元各自是否是模板是相互无关的.如果一个类模板包含一个非模板友元,则友元被授权可以访问所有模板实例.如果友元自身是模板,类可以授权给所有友元模板实例,也可以只授权给特定 ...
- 自定义动画(仿Win10加载动画)
一.源代码 源代码及demo 二.背景 先看看Win10的加载动画(找了很久才找到): CPA推广甲爪广告联盟满30日结 [点击进入] 甲爪广告联盟,提供各类高单价CPA广告 单价高 收益好 日付广告 ...
- 微信小程序开发11-HTTPS网络通信(重点)
1.OneNET平台支持https,将HTTP头部改成https://api.heclouds.com即可(重点!!!!!!!!) 2.如果我们需要从 https://test.com/getinfo ...
- 屏幕录像LICEcap
简介 LiceCap是一款轻量级屏幕录制工具 官网链接 windows版下载链接 Demo 以下是访问http://www.cockos.com/licecap/的屏幕录像
- Oracle PL/SQL Dev工具(破解版)被植入勒索病毒的安全预警及自查通告
[问题描述] 近日,有项目组遇到了勒索软件攻击:勒索代码隐藏在Oracle PL/SQL Dev软件中(网上下载的破解版),里面的一个文件afterconnet.sql被黑客注入了病毒代码.这个代码会 ...
- 从golang-gin-realworld-example-app项目学写httpapi (二)
https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/models.go 模型定义 use ...
- java笔记--重定向输出流实现程序输出到日志
重定向输出流实现程序输出到日志 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877248.html "谢谢-- 利用Sy ...
- LNMP-day1-安装并配置
Nginx安装 #Nginx [root@localhost downloads]# pwd /root/downloads #安装依赖pcre [root@localhost downloads]# ...
- codeforces 407C Curious Array
codeforces 407C Curious Array UPD: 我觉得这个做法比较好理解啊 参考题解:https://www.cnblogs.com/ChopsticksAN/p/4908377 ...