java 浅复制和深复制

原文:http://ttitfly.iteye.com/blog/155422

1.java里的clone分为: 
A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 
b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍。 
Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。必须要遵循下面三点 
1.在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。 
2.在派生类的clone()方法中,调用super.clone()。 
3.在派生类中实现Cloneable接口。 

Object类里的clone方法是浅复制(浅克隆) 

浅复制(浅克隆)的例子如下: 

package com.test;

//浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
//深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍。
//
//Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。必须要遵循下面三点
//1.在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
//2.在派生类的clone()方法中,调用super.clone()。
//3.在派生类中实现Cloneable接口。

//[color=red]Object类里的clone方法是浅复制(浅克隆)[/color]public class CloneTest {

	public static void main(String[] args) throws Exception{
		//teacher对象将被clone出来的Student对象共享.
		Teacher teacher = new Teacher();
		teacher.setAge(40);
		teacher.setName("Teacher zhang");

		Student student1 = new Student();
		student1.setAge(20);
		student1.setName("zhangsan");
		student1.setTeacher(teacher);

		//复制出来一个对象student2
		Student student2 = (Student)student1.clone();
		System.out.println(student2.getAge());
		System.out.println(student2.getName());

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());

		//修改student2的引用对象
		student2.getTeacher().setAge(50);
		student2.getTeacher().setName("Teacher Li");

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());
	}
}

class Teacher {
	public int age;
	public String name;

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

}

class Student implements Cloneable{

	public int age ;
	public String name;
	public Teacher teacher;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

}
输出结果为:
20
zhangsan
~~~~~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~~~~~
50
Teacher Li

2.深复制(深Clone)例子: 

package com.test1;

//深clone
public class DeepCloneTest {

	public static void main(String[] args) throws Exception{
		//teacher对象将不被clone出来的Student对象共享.
		Teacher teacher = new Teacher();
		teacher.setAge(40);
		teacher.setName("Teacher zhang");

		Student student1 = new Student();
		student1.setAge(20);
		student1.setName("zhangsan");
		student1.setTeacher(teacher);

		//复制出来一个对象student2
		Student student2 = (Student)student1.clone();
		System.out.println(student2.getAge());
		System.out.println(student2.getName());

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());

		//修改student2的引用对象
		student2.getTeacher().setAge(50);
		student2.getTeacher().setName("Teacher Li");

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());
	}
}

class Teacher implements Cloneable{
	public int age;
	public String name;

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

}

class Student implements Cloneable{

	public int age ;
	public String name;
	public Teacher teacher;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		Student student = (Student)super.clone();
		//将引用的对象teacher也clone下
		student.setTeacher((Teacher)(student.getTeacher().clone()));
		return student;
	}

}
输出结果为:
20
zhangsan
~~~~~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~~~~~
40
Teacher zhang

3.利用序列化来做深复制,把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。,利用这个特性,可以做深拷贝 

package com.test3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
//利用序列化来做深复制
//深clone
public class DeepCloneTest {

	public static void main(String[] args) throws Exception{
		//teacher对象将不被clone出来的Student对象共享.
		Teacher teacher = new Teacher();
		teacher.setAge(40);
		teacher.setName("Teacher zhang");

		Student student1 = new Student();
		student1.setAge(20);
		student1.setName("zhangsan");
		student1.setTeacher(teacher);

		//复制出来一个对象student2
		Student student2 = (Student)student1.deepCopy();
		System.out.println(student2.getAge());
		System.out.println(student2.getName());

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());

		//修改student2的引用对象
		student2.getTeacher().setAge(50);
		student2.getTeacher().setName("Teacher Li");

		System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(student1.getTeacher().getAge());
		System.out.println(student1.getTeacher().getName());
	}
}

class Teacher implements Serializable{

	private static final long serialVersionUID = -8834559347461591191L;

	public int age;
	public String name;

	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

}

class Student implements Serializable{

	//serialVersionUID 如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。
	//但当serialVersionUID相同时,它就会将不一样的field以type的缺省值赋值(如int型的是0,String型的是null等),这个可以避开不兼容性的问题。所以最好给serialVersionUID赋值
	private static final long serialVersionUID = 7991552226614088458L;

	public int age ;
	public String name;
	public Teacher teacher;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}

	public Object deepCopy() throws Exception{
		//将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		ObjectOutputStream oos = new ObjectOutputStream(bos);

		oos.writeObject(this);

		//将流序列化成对象
		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

		ObjectInputStream ois = new ObjectInputStream(bis);

		return ois.readObject();
	}

}
输出结果为:
20
zhangsan
~~~~~~~~~~~~~~~~~~~~~~
40
Teacher zhang
~~~~~~~~~~~~~~~~~~~~~~
40
Teacher zhang
时间: 2025-01-27 13:47:12

java 浅复制和深复制的相关文章

android 浅复制和深复制-Java Generic Deep Copy 篇

关于Java Generic Deep Copy 在java中的应用和注意事项,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7039425 而关于在android程序中通过clone方法来进行浅复制和深复制,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7036818 众所周知,android上层使用的是java语言,因此理论上于Java Generic De

Java中对象的深复制和浅复制详解

1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆) 被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用的对象都复制了一遍. 2.Java的clone()方法 ⑴clone方法将对象复制了一份并返回

Java中的深拷贝(深复制)和浅拷贝(浅复制)介绍_java

深拷贝(深复制)和浅拷贝(浅复制)是两个比较通用的概念,尤其在C++语言中,若不弄懂,则会在delete的时候出问题,但是我们在这幸好用的是Java.虽然java自动管理对象的回收,但对于深拷贝(深复制)和浅拷贝(浅复制),我们还是要给予足够的重视,因为有时这两个概念往往会给我们带来不小的困惑. 浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象.深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象.举例来说更加清楚:对象A1中包含对B1的引用

Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍_java

1.浅复制与深复制概念 ⑴浅复制(浅克隆)      被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆)      被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用的对象都复制了一遍. 2.Java的clone()方法 ⑴clone方法将

java中对象的浅复制和深复制笔记

在面向对象的语言中,如Java/Python,对象的复制有两种形式:浅复制和深复制 一.浅复制    浅复制只是将原对象的引用备份了一份给新的变量,实际两者指向的是同一个对象.在Python中,字典.列表.元祖等都是对象类型 >>> person=['name',['savings',100.00]] >>> hubby=person[:] >>> wifely=list(person) >>> [id(x) for x in per

android 浅复制和深复制-clone篇

有关java中的 浅复制和深复制 ,这里不详细讨论.相关知识请参考以下帖子: 浅复制和深复制http://blog.csdn.net/yang_hui1986527/article/details/7029777 浅析Java中的深拷贝与浅拷贝http://blog.csdn.net/yang_hui1986527/article/details/7012428 android中的 浅复制和深复制,具体可能于java中的有一点不同.下面,我们来探讨下在这个问题. 主要思路: 1.创建TextBo

浅析:对象的浅复制和深复制

问题描述 在面向对象的语言中,如Java/Python,对象的复制有两种形式:浅复制和深复制一.浅复制浅复制只是将原对象的引用备份了一份给新的变量,实际两者指向的是同一个对象.在Python中,字典.列表.元祖等都是对象类型>>> person=['name',]>>> hubby=person>>> wifely=list(person)>>> >>>person是一个列表对象,分割之后赋给hubby,将perso

深度解析javascript中的浅复制和深复制

     在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有 Number,Boolean,String,Null,Undefined,Object五种类型.而Object又包含Function,Array 和Object自身.前面的五种类型叫做基本类型,而Object是引用类型.可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的.      我们首先来看看浅复制和深复制的简洁定义: 深复制:直接将数据复制给对应的变量 浅复制:将数据的地

举例区分Python中的浅复制与深复制

  这篇文章主要介绍了举例区分Python中的浅复制与深复制,是Python入门学习中的重要知识,需要的朋友可以参考下 copy模块用于对象的拷贝操作.该模块非常简单,只提供了两个主要的方法: copy.copy 与 copy.deepcopy ,分别表示浅复制与深复制.什么是浅复制,什么是深复制,网上有一卡车一卡车的资料,这里不作详细介绍.复制操作只对复合对象有效.用简单的例子来分别介绍这两个方法. 浅复制只复制对象本身,没有复制该对象所引用的对象. ? 1 2 3 4 5 6 7 8 9 1

php中浅复制与深复制的例子

周末闲来无事看到了原型模式,其中谈到了浅复制和深复制,想到PHP中的对应赋值.克隆以及克隆是浅复制还是深复制. 先来看看赋值,例如有一个简历类,有身高和体重两个属性: class Resume  {     public $height;     public $weight;       public $workExperience; } $ResumeA = new Resume(); $ResumeB = $ResumeA; 此时实例化了一个Resume类并赋值给了$ResumeA变量,然