博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java对象复制
阅读量:6825 次
发布时间:2019-06-26

本文共 10751 字,大约阅读时间需要 35 分钟。

  hot3.png

1.Java对象复制概念

    1.1 浅复制(浅克隆)

        复制的对象的所有变量与含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

    1.2 深复制(深度克隆)

        复制的对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向复制的新对象,而不是原来的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

2.Java对象的clone()克隆方法

    2.1 clone方法

    clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足

  • 对任何的对象x,都有x.clone() != x;也即克隆的对象与原对象不是同一个对象,他们有不同的内存地址
  • 对任何的对象x,都有x.clone().getClass() == x.getClass(),也即克隆对象与原对象的类型一致。
  • 如果对象x的equals()方法定义恰当,那么x.clone().equal(x)应该成立。

    2.2 Java中对象的克隆

  • 为了获取对象的一份拷贝,我们可以利用Object的clone()方法
  • 在派生类中覆盖基类的clone()方法,并声明为public
  • 在派生类的clone()方法中,调用super.clone()。
  • 在派生类中实现Cloneable接口

    2.3 示例

    2.3.1 浅复制示例

package org.wem.im;/** *  * 

* Title: Person

* Copyright: Copyright (c) 2016
* Company:
*

* *

* Description: 测试Java对象浅克隆 *

* * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:28:22 * * Modification History: *---------------------------------------------------------* * */public class Person implements Cloneable { class Worker{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.clone(); System.out.println("原对象信息:"+p.toString()); System.out.println("克隆对象信息:"+p_clone.toString()); //修改p_clone对象的值 p_clone.setName("kucs_clone"); //修改对象引用的对象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改后的克隆对象信息:"+p_clone.toString()); System.out.println("原对象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("浅复制对象,其引用的对象未复制"); }else{ System.out.println("非浅复制对象,其引用的对象也复制"); } }}

运行结果

原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]克隆对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]修改后的克隆对象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]]原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]]浅复制对象,其引用的对象未复制

结果说明:浅克隆之后的对象与原对象不是同一个对象。修改其中一个对象的值对另一个对象没有影响。

                浅克隆中其引用的对象未复制,还是指向同一个对象。

    2.3.2 深复制示例

        对浅复制示例代码做了调整

package org.wem.im;/** *  * 

* Title: Person

* Copyright: Copyright (c) 2016
* Company:
*

* *

* Description: 测试Java对象深度克隆 *

* * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:45:22 * * Modification History: *---------------------------------------------------------* * */public class Person implements Cloneable { class Worker implements Cloneable{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Person p = (Person) super.clone(); p.worker = (Worker) worker.clone(); return p; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.clone(); System.out.println("原对象信息:"+p.toString()); System.out.println("克隆对象信息:"+p_clone.toString()); //修改p_clone对象的值 p_clone.setName("kucs_clone"); //修改对象引用的对象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改后的克隆对象信息:"+p_clone.toString()); System.out.println("原对象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("浅复制对象,其引用的对象未复制"); }else{ System.out.println("非浅复制对象,其引用的对象也复制"); } }}

    运行结果:

原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]克隆对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]修改后的克隆对象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]]非浅复制对象,其引用的对象也复制

    结果说明:深克隆中,对克隆后的对象修改值,不影响原对象的值。修改克隆后的对象引用的值,对原对象引用的对象也没有影响。

3.利用串行化来做深复制

    这主要是为了避免重写比较复杂的深复制clone()方法。把对象写到流里的过程是串行化过程(Serialization),把对象从流中读取出来是并行化(Deserialization)过程。

    注意:写在流里的对象时一个拷贝,而原对象仍然存在jvm中,因此串行化过程只是一个对象的拷贝。

    在Java语言中,深复制一个对象,常常可以先使用对象实现Serializable接口,然后把对象写到一个流里,再从流里读取出来,便可以重建对象。

package org.wem.im;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;/** *  * 

* Title: Person

* Copyright: Copyright (c) 2016
* Company:
*

* *

* Description: 测试Java对象克隆 *

* * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:28:22 * * Modification History: *---------------------------------------------------------* * */public class Person implements Serializable { class Worker implements Serializable{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } public Object deepClone() throws IOException, 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(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.deepClone(); System.out.println("原对象信息:"+p.toString()); System.out.println("克隆对象信息:"+p_clone.toString()); //修改p_clone对象的值 p_clone.setName("kucs_clone"); //修改对象引用的对象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改后的克隆对象信息:"+p_clone.toString()); System.out.println("原对象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("浅复制对象,其引用的对象未复制"); }else{ System.out.println("非浅复制对象,其引用的对象也复制"); } }}

运行结果

原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]克隆对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]修改后的克隆对象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]]原对象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]]非浅复制对象,其引用的对象也复制

 

转载于:https://my.oschina.net/mrku/blog/753821

你可能感兴趣的文章
我的友情链接
查看>>
关于cisco交换机的config.text和startup-config
查看>>
可执行JAR读写内外文件
查看>>
libsvm for python学习(2)
查看>>
Windows+Apache搭建PHP开发环境
查看>>
lamp环境测试php问题
查看>>
Handbook of Constraints Programming——Chapter4 Backtracking Search Algorithms-Preliminaries
查看>>
[转载] 信息系统项目管理师视频教程——14 项目进度管理
查看>>
linux 解压文件
查看>>
区块链学习指南
查看>>
LINUX-软件安装(四)
查看>>
JavaScript学习总结(5)——Javascript面向(基于)对象编程
查看>>
Ansible入门
查看>>
Spring常用注解
查看>>
SVN学习总结(1)——SVN简介及入门使用
查看>>
浅谈linux性能调优之五:调优软raid
查看>>
Android sdk下载缓慢解决方式
查看>>
Q+无法启动?启动后立即退出?折腾……
查看>>
SQL2008不能删除过期备份
查看>>
IBM TPC强化中国建设银行存储管理能力
查看>>