关键字: 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# 语言编程中,深度复制和浅度复制,下面我将通过一个实例进行讲解。在实例开发之前,我们得先知道深度复制是什么和浅度复制是什么,它们之间的区别又是什么,下面将为大家一一揭晓。 1.深度复制是...
c#深度复制浅度复制
本文深入浅出的分析了ASP.NET深度复制和浅度复制。分享给大家供大家参考。具体分析如下: 之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉。 如果大家不懂值...
主要介绍了Java中的深拷贝(深复制)和浅拷贝(浅复制)介绍,需要的朋友可以参考下
本篇文章是对JAVA深度克隆与浅度克隆的区别进行了详细的分析介绍,需要的朋友参考下
基于java实现浅度爬虫应用,是我学习java来练练手的,java爬虫基础入门的学生可以考虑参考一下
主要介绍了vue.js浅度监听和深度监听及watch用法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
网络语言浅度研究报告.doc
浅度探索C++对象模型bin3.ppt
内容有:1.ajax入门的三个好例子,很值得学习和借鉴的地方,循序渐进的学习方法 2.ajax的方法从零开始讲起,如何实现,简单明了 3.java的重点介绍,不是纯粹的说说java的语法,既有浅度也有深度,我认为学...
NULL 博文链接:https://lzy.iteye.com/blog/407956
大家是否觉得MyEclipse启动很慢,那么来看一下吧,如果谁有其他的优化方法,欢迎交流!
主要介绍了C#浅拷贝和深拷贝,是比较重要的概念,需要的朋友可以参考下
踏入C++的世界已经两年了,但一直在黑夜中前行,最近看到了由Lostmouse 译的Scott Meyers的著作《EffectiveC++》的中文版电子书,犹如一盏指路明灯,照亮了我前进的路。这本书由lians制作,由save 修订。...
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...
介绍了人工智能技术的相关概念、发展概述及其在煤炭行业发展中的应用,指出目前人工智能技术在矿山应用只是点状结合和浅度结合,没有实现人工智能技术和矿山某个生产或管理系统层面的深度融合。概述了智能矿山的发展...
创建型模式中一个比较特殊的模式-原型模式,有个最大的特点是克隆一个现有的对象,这个克隆的结果有2种,一种是浅度复制,另一种是深度复制。 创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些...