Java 深复制和浅复制
浅复制是指复制对象时仅仅复制对象本身(包括对象中的基本变量),而不复制对象包含的引用指向的对象。深复制不仅复制对象本身,而且复制对象包含的引用指向的对象。
复制对象时需要调用Object类的clone方法:
protected native Object clone() throws CloneNotSupportedException;
步骤:
1 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法时会抛出CloneNotSupportedException异常) 。而该接口为标记接口(不含任何抽象方法)。
2 重写clone()方法,访问修饰符设为public,通过调用super.clone()方法得到需要的复制对象。
浅复制
class Address {
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
}
class Student implements Cloneable{
private int number;
private Address addr;
public Address getAddr() {
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
}
public class Test {
public static void main(String args[]) {
Address addr = new Address();
addr.setAdd("杭州市");
Student stu1 = new Student();
stu1.setNumber(123);
stu1.setAddr(addr);
Student stu2 = (Student)stu1.clone();
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
addr.setAdd("西湖区");
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
}
}
结果如下:
学生1:123,地址:杭州市
学生2:123,地址:杭州市
学生1:123,地址:杭州市
学生2:123,地址:杭州市
学生1:123,地址:西湖区
学生2:123,地址:西湖区
两个学生的地址都改变了。原因是浅复制只是复制了addr变量的引用,并没有真正地开辟另一块空间来存储地址对象。
深复制
class Address implements Cloneable {
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
@Override
public Object clone() {
Address addr = null;
try{
addr = (Address)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return addr;
}
}
class Student implements Cloneable{
private int number;
private Address addr;
public Address getAddr() {
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone(); //浅复制
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
stu.addr = (Address)addr.clone(); //深度复制
return stu;
}
}
public class Test {
public static void main(String args[]) {
Address addr = new Address();
addr.setAdd("杭州市");
Student stu1 = new Student();
stu1.setNumber(123);
stu1.setAddr(addr);
Student stu2 = (Student)stu1.clone();
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
addr.setAdd("西湖区");
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
}
}
结果如下:
学生1:123,地址:杭州市
学生2:123,地址:杭州市
学生1:123,地址:西湖区
学生2:123,地址:杭州市
参考资料
java.util.ArrayList.clone是不是彻底的克隆
Java 深复制和浅复制的更多相关文章
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- Java中的深复制与浅复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- Java中的clone()----深复制,浅复制
这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他 ...
- clone()方法、深复制和浅复制
clone方法 Java中没有明确提供指针的概念和用法,而实质上没个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如何去操作这个指针而已. 在实际编程中,经常会遇到从某个已 ...
- js中的深复制与浅复制
前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...
- .Net深复制、浅复制
在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...
- C++学习基础七——深复制与浅复制
一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...
- php对象当参数传递 && php深复制和浅复制
把对象当参数传递给方法,在方法里改过对象后,影响到外面的对象 因为对象是引用传递过去的 class Book { public $name; public function __construct( ...
- iOS 集合的深复制与浅复制
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...
- C#深复制和浅复制
本文在于巩固基础 我们来看看什么是深复制.浅复制: C#中对于数据的复制机制虽然简单但是容易让人误解.C#数据类型大体分为值类型(value type)与引用类型(reference type).对于 ...
随机推荐
- 社会单位消防安全户籍化管理系统——半自动提交V1.0版本
社会单位消防安全户籍化管理系统——半自动提交V1.0版本 首先先上代码,开发这个小程序其实是用来帮助同事完成一项每天都做的繁琐事件,以往需要花费十分钟做这件事情,现在就是傻瓜式,点几下鼠标就好了.本来 ...
- 网络通信socket连接数上限
socket accept()返回的socket描述符的端口和listen描述符端口是一样的吗? as you know,一个socket是由一个五元组来唯一标示的,即(协议,server_ip, s ...
- WPF 对控件进行截图且不丢失范围(转载)
原文:Taking WPF “Screenshots” I was recently working on a Surface project at Microsoft (that will be s ...
- Java-把日期字符串转换成另一种格式的日期字符串
package com.example.demo.utils; import java.text.ParseException; import java.text.SimpleDateFormat; ...
- sdoi2017苹果树
题解: 非常奇妙的一题.. 没有免费操作我都不会$nk$....考试打个暴力就可以走人了 树上有依赖背包问题的正确做法是(为啥我之前学的不是这样的啊) 按照后续遍历做背包 做到一个点的时候 枚举它选不 ...
- LVM管理之减少LV的大小
LVM管理之减少LV的大小 规定动作 1.umount filesystem 2.e2fsck filesystem 3.resize2fs filesystem 4.lvredure 实例演示——— ...
- Codeforces 1137D Cooperative Game (看题解)
Cooperative Game 智商题, 感觉不太能推出来, 虽然看看证明过程是对的. #include<bits/stdc++.h> #define LL long long #def ...
- 2n的 位数
len=())+,(2n−1同样适用)
- 通过mysql-proxy映射外网访问内网数据库
配置教程: 转自:http://www.centoscn.com/mysql/2015/0107/4437.html centos安装mysql-proxy mysql-proxy的用处就不再说了 m ...
- TensorFlow图像预处理-函数
更多的基本的API请参看TensorFlow中文社区:http://www.tensorfly.cn/tfdoc/api_docs/python/array_ops.html 下面是实验的代码,可以参 ...