- 浏览: 177243 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
jiasky:
好像是在练书法。
Oracle Function -
blackangel_can:
这样的代码见得多了。
Javascript Print(*) -
tianhendi:
Apache Solr and Tomcat6 Search engine -
laserdance:
我想问下,你怎么从Tomcat等服务器中把上述文件xml准确定 ...
Java parse XML methods(4) -
cskysnew:
第二种如果去掉synchronized,就不是线程安全的,应该 ...
Singlton ture or not?
Java中的浅复制与深复制
分析一下Java中关于浅复制与深复制的问题。探讨浅复制与深复制的概念、clone()方法和利用串行化做深复制的实现。
浅复制与深复制概念
1.1浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。1.2深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。 2.Java的clone()方法
2.1 clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。 2.2 Java中对象的克隆
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
请看如下代码: class Student implements Cloneable{
String name;
int age;
Student(String name,int age) {
this.name=name;
this.age=age;
}
public Object clone() {
Object o=null;
try {
o=(Student)super.clone();//Object中的clone()识别出你要复制的是哪一个对象。
}
catch(CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
} public static void main(String[] args) {
Student s1=new Student("zhangsan",18);
Student s2=(Student)s1.clone();
s2.name="lisi";
s2.age=20;
System.out.println("name="+s1.name+","+"age="+s1.age);//修改学生2后,不影响学生1的值。
} 说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
②继承自java.lang.Object类的clone()方法是浅复制。
以下代码可以证明之。
class Professor {
String name;
int age;
Professor(String name,int age) {
this.name=name;
this.age=age;
}
}
class Student implements Cloneable{
String name;//常量对象。
int age;
Professor p;//学生1和学生2的引用值都是一样的。
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 static void main(String[] args) {
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.clone();
s2.p.name="lisi";
s2.p.age=30;
System.out.println("name="+s1.p.name+","+"age="+s1.p.age); //学生1的教授成为lisi,age为30。
} 那应该如何实现深层次的克隆,即修改s2的教授不会影响s1的教授?
代码改进如下。 改进使学生1的Professor不改变(深层次的克隆)
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 static void main(String[] args) {
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.clone();
s2.p.name="lisi";
s2.p.age=30;
System.out.println("name="+s1.p.name+","+"age="+s1.p.age); //学生1的教授不改变。
}
3.利用串行化来做深复制
把对象写到流里的过程是串行化(Serilization)过程,但是在Java程序师圈子里又非常形象地称为“冷冻”或者“腌咸菜(picking)”过程;而把对象从流中读出来的并行化(Deserialization)过程则叫做“解冻”或者“回鲜(depicking)”过程。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此“腌成咸菜”的只是对象的一个拷贝,Java咸菜还可以回鲜。
在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成咸菜),再从流里读出来(把咸菜回鲜),便可以重建对象。
如下为深复制源代码。
public Object deepClone()
{
//将对象写到流里
ByteArrayOutoutStream 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());
} 这样做的前提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可串行化的对象可否设成transient,从而将之排除在复制过程之外。上例代码改进如下。
class Professor implements Serializable{
String name;
int age;
Professor(String name,int age) {
this.name=name;
this.age=age;
}
}
class Student implements Serializable{
String name;//常量对象。
int age;
Professor p;//学生1和学生2的引用值都是一样的。
Student(String name,int age,Professor p) {
this.name=name;
this.age=age;
this.p=p;
}
public Object deepClone() throws IOException,
OptionalDataException,ClassNotFoundException{
//将对象写到流里
ByteArrayOutoutStream 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 static void main(String[] args) {
Professor p=new Professor("wangwu",50);
Student s1=new Student("zhangsan",18,p);
Student s2=(Student)s1.deepClone();
s2.p.name="lisi";
s2.p.age=30;
System.out.println("name="+s1.p.name+","+"age="+s1.p.age); //学生1的教授不改变。
}
发表评论
-
移动电商
2016-04-19 18:13 551海外旅行购物电商平台-购轻松,是我们从零开发的App应用,欢迎 ... -
Top 10 Books For Advanced Level Java Developers
2013-11-03 21:59 526Top 10 Books For Advanced Level ... -
RESTful
2013-10-28 22:28 677要使API易用、易于接受和足够灵活,应该遵循以下原则: An ... -
Androd app
2012-08-19 21:35 806an android app -
Jenkins-CI
2012-06-30 08:26 796Jenkins for java and .net CI. -
JNLP
2009-04-20 13:26 1162<?xml version="1.0" ... -
Eclipse3.4 + Axis2 Configuration
2009-03-12 19:53 16051) Download the axis2 v1.4 plug ... -
XML configuration for Spring jsf hibernate
2008-07-16 13:51 1120faces-comfig.xml <?xml ver ... -
Final Usage
2008-04-29 21:05 912final在Java中并不常用,然而它却为我们提供了诸如在C语 ... -
Java tips
2008-03-03 21:39 757// 程序1 class Singleton { priv ... -
Java Connect Pool
2008-02-24 19:13 1996import java.io.*; import java.s ... -
Apache Solr and Tomcat6 Search engine
2008-01-04 13:51 2584Today, test the Solr and Tomcat ... -
Java Multiple process (PID)
2007-12-11 11:29 5946Java的多进程运行模式分析 一般我们在java中运行其它类中 ... -
Glassfish V2 And NetBean6
2007-12-05 16:33 1538Dowload Netbean6 from http://ne ... -
Spring用回调HibernateCallBack方法
2007-11-05 15:45 2945Spring用回调HibernateCallBack方法实现持 ... -
Future pattern
2007-11-04 19:54 2159个人理解 Future 模式就是在主线程中当需要进行比较耗时的 ... -
Log4j Configuration (Recitation)
2007-10-14 20:41 2315一、常用输出格式 %c 列出logger名字空间的全称,如加 ... -
JasperReport usage
2007-09-27 22:07 1194jasperreport tools enhance and ... -
Lucene practice
2007-09-19 22:23 10531.simply practice the lucene ap ... -
Java中的序列化(转)
2007-09-08 07:29 12191、序列化是干什么的? 简单说就是为了保存在内存中的各种 ...
相关推荐
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
本文将深入探讨Java中的浅复制和深复制,并以Android为背景,结合具体的实例讲解如何实现Java泛型深拷贝。 首先,我们要理解浅复制和深复制的概念。浅复制(Shallow Copy)是指创建一个新的对象,然后将原对象引用...
在Java中,当我们使用`clone()`方法或`System.arraycopy()`进行复制时,通常得到的是浅复制的结果。这意味着原始对象和复制对象中的引用指向内存中的同一块区域。如果List中的元素是基本类型,这种复制方式是没问题...
### Java的深复制与浅复制 #### 一、概述 在Java编程中,对象的复制是一个常见的需求。复制对象的目的通常是为了保留一个备份或者创建一个新的实例来避免对原始对象的修改影响到其他部分的程序逻辑。Java提供了两...
本篇文章将深入探讨Java中的深复制和浅复制概念,并通过源代码示例进行详细解析。 首先,我们理解一下深复制和浅复制的区别: 1. **浅复制(Shallow Copy)**:浅复制只是复制了对象的引用,而不是对象本身。这...
在Java编程中,复制对象是常见的操作,主要分为两种方式:浅复制(Shallow Copy)和深复制(Deep Copy)。这两种复制方式的区别在于处理对象内部引用其他对象的情况。 1. **浅复制(浅克隆)**: 浅复制是指创建一...
在Java编程语言中,对象复制是一个常见的操作,...理解并正确使用浅复制和深复制对于开发高效、健壮的Java应用程序至关重要。在处理复杂的数据结构时,应根据需求选择合适的复制策略,以避免不必要的副作用和数据污染。
在实际编程中,选择浅复制还是深复制取决于你的需求。如果对象的属性不包含对其他对象的引用,或者你希望修改副本不会影响原始对象,那么浅复制可能是足够的。然而,如果你的对象包含复杂的嵌套结构,或者需要保持...
为了理解深拷贝(深复制)和浅拷贝(浅复制),我们需要首先了解Java对象内存的分配方式以及引用的概念。 1. **对象复制的基础** 在Java中,当我们创建一个对象时,系统会在内存中为该对象分配一块空间,存储它的...
在Java中,浅复制可以通过实现`Cloneable`接口并覆盖`clone()`方法来完成。 ```java public class Person implements Cloneable { String name; Address address; // ... 构造器、getter和setter等 @Override...
在Java编程语言中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是两种不同的对象复制方式,它们涉及到内存中数据的复制和引用的处理。理解这两种拷贝方式对于开发过程中正确管理和操作对象至关重要。 浅拷贝,又...
在Java中,对象的复制分为浅复制和深度复制两种。浅复制是指创建一个新的对象,并将原对象的非引用类型的字段值复制到新对象中;对于引用类型的字段,只是复制了引用地址,即新旧对象共享同一份数据。而深度复制则是...
在本文中,我们介绍了 Java 浅复制和深复制的实例详解,通过代码示例和结果分析,我们可以看到浅复制和深复制的区别和应用场景。浅复制适用于简单的对象复制,而深复制适用于需要完全复制对象的场景。
Java对象深复制与浅复制是Java编程中两个重要的概念,它们都是对象复制的方式,但它们有着不同的实现机制和应用场景。在本文中,我们将详细介绍Java对象深复制与浅复制的概念、实现机制、应用场景和示例代码。 浅...
在Java编程中,深复制和浅复制是两个重要的概念,主要涉及到对象的复制与克隆。这两个术语在处理对象的拷贝时具有不同的含义,理解它们对于编写高效且无误的代码至关重要。 首先,让我们来看一下浅复制(Shallow ...
在Java中,如果类的属性都是基本类型,可以通过构造函数或克隆方法实现浅复制。但如果属性包含引用类型,就需要深复制以确保新对象拥有独立的引用。 3. **注解实现复制**: 注解是一种元数据,可以提供编译时或运行...
在Java编程语言中,克隆是创建一个对象副本的过程,这个副本与原对象有相同的属性值,但作为不同的对象存在。克隆分为两种主要类型:浅克隆(Shallow Clone)和深克隆(Deep Clone)。这篇博客文章将探讨这两种克隆...
首先我们看看浅拷贝和深拷贝的定义 浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制 深拷贝:对象,对象内部的引用均复制 为了更好的理解它们的区别我们假设有一个对象A,它包含...
在Java编程中,对象复制是一项常见的任务,特别是在处理模型(Model)和视图对象(VO)时。模型对象通常用于封装业务数据,而视图对象则用于展示这些数据。值复制,即对象属性值的复制,是保持数据一致性和简化代码...
在Java编程语言中,克隆是一种创建对象副本的方法,它允许我们复制一个对象并拥有一个完全独立的新实例,而不是仅仅引用原始对象。克隆技术在处理复杂数据结构、避免对象共享以及实现对象复制等方面有着广泛的应用。...