`
huobengluantiao8
  • 浏览: 1030817 次
文章分类
社区版块
存档分类
最新评论

java深度复制和浅度复制

 
阅读更多
关键字: java 潜拷贝和深拷贝.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接口。

//<SPAN style="COLOR: red">Object类里的clone方法是浅复制(浅克隆)</SPAN>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

分享到:
评论

相关推荐

    C#中深度复制和浅度复制详解

    本文章主要是讲解C# 语言编程中,深度复制和浅度复制,下面我将通过一个实例进行讲解。在实例开发之前,我们得先知道深度复制是什么和浅度复制是什么,它们之间的区别又是什么,下面将为大家一一揭晓。 1.深度复制是...

    c#深度复制浅度复制

    c#深度复制浅度复制

    ASP.NET深度复制和浅度复制分析

    本文深入浅出的分析了ASP.NET深度复制和浅度复制。分享给大家供大家参考。具体分析如下: 之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉。 如果大家不懂值...

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

    主要介绍了Java中的深拷贝(深复制)和浅拷贝(浅复制)介绍,需要的朋友可以参考下

    解析JAVA深度克隆与浅度克隆的区别详解

    本篇文章是对JAVA深度克隆与浅度克隆的区别进行了详细的分析介绍,需要的朋友参考下

    基于java实现浅度爬虫应用

    基于java实现浅度爬虫应用,是我学习java来练练手的,java爬虫基础入门的学生可以考虑参考一下

    实例详解vue.js浅度监听和深度监听及watch用法

    主要介绍了vue.js浅度监听和深度监听及watch用法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧

    网络语言浅度研究报告.doc

    网络语言浅度研究报告.doc

    浅度探索C++对象模型bin3.ppt

    浅度探索C++对象模型bin3.ppt

    ajax从基础学起

    内容有:1.ajax入门的三个好例子,很值得学习和借鉴的地方,循序渐进的学习方法 2.ajax的方法从零开始讲起,如何实现,简单明了 3.java的重点介绍,不是纯粹的说说java的语法,既有浅度也有深度,我认为学...

    JRE Hack 浅度研究

    NULL 博文链接:https://lzy.iteye.com/blog/407956

    MyEclipse浅度优化方法

    大家是否觉得MyEclipse启动很慢,那么来看一下吧,如果谁有其他的优化方法,欢迎交流!

    C#浅拷贝和深拷贝实例解析

    主要介绍了C#浅拷贝和深拷贝,是比较重要的概念,需要的朋友可以参考下

    浅度解析C++运算符重载

    踏入C++的世界已经两年了,但一直在黑夜中前行,最近看到了由Lostmouse 译的Scott Meyers的著作《EffectiveC++》的中文版电子书,犹如一盏指路明灯,照亮了我前进的路。这本书由lians制作,由save 修订。...

    .NET之美:.NET关键技术深入分析

    1.3.1 浅度复制 1.3.2深度复制 1.4不可变类型 1.4.1从类型设计谈起,Class还是Struct 1.4.2数据不一致的问题 1.4.3 常量性和原子性 1.4.4避免外部类型对类型内部的访问 1.5本章小结 第2章C#中的泛型 2.1...

    人工智能技术在矿山智能化建设中的应用初探

    介绍了人工智能技术的相关概念、发展概述及其在煤炭行业发展中的应用,指出目前人工智能技术在矿山应用只是点状结合和浅度结合,没有实现人工智能技术和矿山某个生产或管理系统层面的深度融合。概述了智能矿山的发展...

    .NET原型模式讲解

    创建型模式中一个比较特殊的模式-原型模式,有个最大的特点是克隆一个现有的对象,这个克隆的结果有2种,一种是浅度复制,另一种是深度复制。 创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些...

Global site tag (gtag.js) - Google Analytics