序列化和依次克隆各个可变的引用类型都可以实现深克隆,但是序列化的效率并不理想

下面是两种实现深克隆的实例,并且测试类对两种方法进行了对比:

1、重写clone方法使用父类中的clone()方法实现深克隆

package com.lk.B;

public class Worker implements Cloneable{
private String name;
private int age;
public Worker(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append("姓名:"+name+",");
sb.append("年龄:"+age+"\n");
return sb.toString();
}
@Override
protected Worker clone() {
// TODO Auto-generated method stub
Worker worker = null;
try {
worker = (Worker) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return worker;
}
}

  2、重写clone()方法使用序列化方法实现深克隆

package com.lk.B;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; public class Employee implements Cloneable,Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Employee(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append("姓名:"+name+",");
sb.append("年龄:"+age+"\n");
return sb.toString();
}
@Override
protected Employee clone() {
// TODO Auto-generated method stub
Employee employss = null; ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try {
ObjectInputStream ois = new ObjectInputStream(bais);
employss = (Employee) ois.readObject();
ois.close();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return employss;
}
}

  两者的实现方式在上面已经列出来了

下面编写了一个测试类来测试两种方式的效率

package com.lk.B;

import java.util.ArrayList;
import java.util.List; public class Test3 {
public static void main(String[] args) {
List<Worker> workerList = new ArrayList<Worker>();//保存Worker对象
List<Employee> employeelist = new ArrayList<Employee>();//保存Employee对象
Worker worker = new Worker("阿坤", 21);
Employee employee = new Employee("阿坤", 21);
long time = System.currentTimeMillis();//取得系统当前时间
//保存10000个Worker对象复制品到列表
for(int i=0;i<10000;i++){
workerList.add(worker.clone());
}
System.out.println("使用复制域的方式实现克隆所花费的时间:"+(System.currentTimeMillis()-time)+"ms");
time = System.currentTimeMillis();//取得系统当前时间
//保存10000个Employee对象复制品到列表
for(int i=0;i<10000;i++){
employeelist.add(employee.clone());
}
System.out.println("使用复制域的方式实现克隆所花费的时间:"+(System.currentTimeMillis()-time)+"ms");
}
}

  运行结果:

/*
使用复制域的方式实现克隆所花费的时间:4ms
使用复制域的方式实现克隆所花费的时间:838ms
*/

  可以看出,可以使用序列化和逐个复制引用类型域的方式完成深克隆,其中序列化的方式效率很低。

Java实现深克隆的两种方式的更多相关文章

  1. 对Java代码加密的两种方式,防止反编译

    使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的j ...

  2. Java新建线程的两种方式

    Java新建线程有两种方式,一种是通过继承Thread类,一种是实现Runnable接口,下面是新建线程的两种方式. 我们假设有个竞赛,有一个选手A做俯卧撑,一个选手B做仰卧起坐.分别为两个线程: p ...

  3. Java实现多线程的两种方式

    实现多线程的两种方式: 方式1: 继承Thread类 A: 自定义MyThread类继承Thread类 B: 在MyThread类中重写run() C: 创建MyThread类的对象 D: 启动线程对 ...

  4. [Java] HashMap遍历的两种方式

    Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml第一种: Map map = new HashMap( ...

  5. java文件读写的两种方式

    今天搞了下java文件的读写,自己也总结了一下,但是不全,只有两种方式,先直接看代码: public static void main(String[] args) throws IOExceptio ...

  6. K:java中序列化的两种方式—Serializable或Externalizable

    在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...

  7. java 实现websocket的两种方式

    简单说明 1.两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket 2.tomcat的方式需要tomcat 7.x,JEE7的支持. 3.spring与we ...

  8. java实现同步的两种方式

    同步是多线程中的重要概念.同步的使用可以保证在多线程运行的环境中,程序不会产生设计之外的错误结果.同步的实现方式有两种,同步方法和同步块,这两种方式都要用到synchronized关键字. 给一个方法 ...

  9. Java线程创建的两种方式

    java多线程总结一:线程的两种创建方式及优劣比较 (一)---之创建线程的两种方式 java实现多线程的两种方法的比较

随机推荐

  1. php连接mysql配置

    php连接mysql测试代码: <?php $link=mysql_connect('localhost','root','123456'); if(!$link) echo "失败! ...

  2. Kafka学习记录

    1 Kafka的基本介绍 Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.具有快速.可扩展.分布式.可复制等特点.Kafka与传 ...

  3. ASP.NET|跳转(redirect)到其它站点,提示:当前线程终止。

    在XAF中,如果使用HttpContext.Response.Redirect()进行跳转,会出现”当前线程终止“的报错,跳转失败. 这时候,应该改用WebApplication.Redirect() ...

  4. HTML to DOM

    Although you can now natively parse HTML using DOMParser and XMLHttpRequest, this is a new feature t ...

  5. 转载:mysql update更新带子查询的实现方式

    出自:http://576017120.iteye.com/blog/1947154 mysql中更新时不能直接将更新的表作为查询的表,可以通过临时中间表的形式. 总结一下: 一:单表更新时 例如: ...

  6. Js 基本数据类型、引用数据类型

    数据类型 1.   ECMAScript变量包含两种不同类型的值:基本类型值.引用类型值: 2.   基本类型值:指的是保存在栈内存中的简单数据段: 3.   引用类型值:指的是那些保存在堆内存中的对 ...

  7. AllocateHwnd is not Thread-Safe

    http://www.thedelphigeek.com/2007/06/allocatehwnd-is-not-thread-safe.html http://gp.17slon.com/gp/fi ...

  8. myeclipse如何导入相应的jar包

    方法一: 相应的项目------>右键------->build path-------->Config BuildPath...------->Libraries------ ...

  9. 【C#】ASP.NET网页中添加单点登录功能

    背景 首先,要说明的是,原先需求定义的是,同一个账号只能同时有一个人来登录,如果另外一个登录的话,前一个登陆者就自动被踢掉.本来原先要做成存储到服务器的数据库中,但是后来如果是非正常退出的话 下次就没 ...

  10. cdoj 48 Cake 水题

    Cake Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/48 Descrip ...