Java中的深拷贝和浅拷贝(转载)
深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java。虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑。
浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
若不对clone()方法进行改写,则调用此方法得到的对象即为浅拷贝,下面我们着重谈一下深拷贝。
运行下面的程序,看一看浅拷贝:
class Professor0 implements Cloneable {
String name;
int age;
Professor0(String name, int age) {
this.name = name;
this.age = age;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student0 implements Cloneable {
String name;// 常量对象。
int age;
Professor0 p;// 学生1和学生2的引用值都是一样的。
Student0(String name, int age, Professor0 p) {
this.name = name;
this.age = age;
this.p = p;
}
public Object clone() {
Student0 o = null;
try {
o = (Student0) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
public class ShallowCopy {
public static void main(String[] args) {
Professor0 p = new Professor0("wangwu", );
Student0 s1 = new Student0("zhangsan", , p);
Student0 s2 = (Student0) s1.clone();
s2.p.name = "lisi";
s2.p.age = ;
s2.name = "z";
s2.age = ;
System.out.println("学生s1的姓名:" + s1.name + "\n学生s1教授的姓名:" + s1.p.name + "," + "\n学生s1教授的年纪" + s1.p.age);// 学生1的教授
}
}
s2变了,但s1也变了,证明s1的p和s2的p指向的是同一个对象。这在我们有的实际需求中,却不是这样,因而我们需要深拷贝:
class Professor implements Cloneable {
String name;
int age;
Professor(String name, int age) {
this.name = name;
this.age = age;
}
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
class Student implements Cloneable {
String name;
int age;
Professor p;
Student(String name, int age, Professor p) {
this.name = name;
this.age = age;
this.p = p;
}
public Object clone() {
Student o = null;
try {
o = (Student) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
o.p = (Professor) p.clone();
return o;
}
}
public class DeepCopy {
public static void main(String args[]) {
long t1 = System.currentTimeMillis();
Professor p = new Professor("wangwu", );
Student s1 = new Student("zhangsan", , p);
Student s2 = (Student) s1.clone();
s2.p.name = "lisi";
s2.p.age = ;
System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age);// 学生1的教授不改变。
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);
}
}
当然我们还有一种深拷贝方法,就是将对象串行化:
import java.io.*;
//Serialization is time-consuming
class Professor2 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
String name;
int age; Professor2(String name, int age) {
this.name = name;
this.age = age;
}
} class Student2 implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
String name;// 常量对象。
int age;
Professor2 p;// 学生1和学生2的引用值都是一样的。 Student2(String name, int age, Professor2 p) {
this.name = name;
this.age = age;
this.p = p;
} public Object deepClone() throws IOException, OptionalDataException,
ClassNotFoundException {
// 将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
} } public class DeepCopy2 { /**
* @param args
*/
public static void main(String[] args) throws OptionalDataException,
IOException, ClassNotFoundException {
long t1 = System.currentTimeMillis();
Professor2 p = new Professor2("wangwu", );
Student2 s1 = new Student2("zhangsan", , p);
Student2 s2 = (Student2) s1.deepClone();
s2.p.name = "lisi";
s2.p.age = ;
System.out.println("name=" + s1.p.name + "," + "age=" + s1.p.age); // 学生1的教授不改变。
long t2 = System.currentTimeMillis();
System.out.println(t2-t1);
} }
但是串行化却很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。
---------------------------------------------------------------------------------------------------------------
注:本文转载于:http://www.cnblogs.com/shuaiwhu/archive/2010/12/14/2065088.html,感谢原文作者!
Java中的深拷贝和浅拷贝(转载)的更多相关文章
- 浅谈Java中的深拷贝和浅拷贝(转载)
浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...
- 浅谈Java中的深拷贝和浅拷贝
转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...
- 内功心法 -- Java中的深拷贝和浅拷贝
写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...
- java中的深拷贝与浅拷贝
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- Java中的深拷贝和浅拷贝
1.浅拷贝与深拷贝概念 (1)浅拷贝(浅克隆) 浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不会影响到源 ...
- java基础(十七)----- 浅谈Java中的深拷贝和浅拷贝 —— 面试必问
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
- 浅析Java中的深拷贝和浅拷
浅析Java中的深拷贝和浅拷贝 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: in ...
- **Python中的深拷贝和浅拷贝详解
Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要 ...
- C语言中的深拷贝和浅拷贝
//C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #inc ...
随机推荐
- 红米手机3S 3X简单卡刷开发版获得ROOT权限的方法
小米的机器不同手机型号一般小米论坛都提供两个不同的系统,即分别是稳定版和开发版,稳定版没有提供root权限管理,开发版中就支持了root权限,很多情况下我们需要使用的一些功能强大的APP,都需要在ro ...
- Leo-io 的C语言实现简单五子棋游戏观后感
源代码: /************************************************************** ** 文 件 名:wuziqi.cpp ** 功 能:扫 ...
- Oracle pl/sql编程值控制结构
以下测试案例均来自于scott方案,运行前请确保该方案解锁. 1.条件分支状语 pl/sql中提供了三种条件分支状语,分别是: if then if then else if then ...
- 使用group by rollup和group by cube后的辅助函数
本文主要介绍,报表在使用group by rollup和group by cube后的辅助函数. CREATE TABLE TEST8 ( "ID" NUMBER, "O ...
- MySQL查询操作select
查找记录 SELECT select_expr [,select_expr ...] [ FROM table_references(表的参照) [WHERE where_condition](条件) ...
- TortoiseGit学习系列之Git和TortoiseGit的区别
不多说,直接上干货! Git和TortoiseGit的区别: TortoiseGit的安装和使用依赖Git.
- 013-PaymentUtils工具类模板
package ${enclosing_package}; import java.io.UnsupportedEncodingException; import java.security.Mess ...
- window server 搭建git服务器
Git服务器Gogs简易安装-Windows环境 1.下载git for windows 1 https://github.com/git-for-windows/git/releases/dow ...
- 大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作
第十九章 Scala语言的数据结构和算法19.1 数据结构(算法)的介绍19.2 看几个实际编程中遇到的问题19.2.1 一个五子棋程序19.2.2 约瑟夫问题(丢手帕问题)19.2.3 其它常见算法 ...
- maven打包报错 ERROR: No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id
打开pom.xml 在build标签中 增加 <defaultGoal>compile</defaultGoal> 如下: <build><defaultGo ...