博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java实现对象克隆的方法
阅读量:6347 次
发布时间:2019-06-22

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

    本文首发于

    转载请注明出处:

前言

这也是昨天的面试题。

当时只说了深拷贝以及浅拷贝,面试官问了两遍还有吗,我很肯定的说就这两种了,面试结束之后查了一下,啪啪打脸。

正文

JAVA实现克隆有两种形式

  • 浅克隆
  • 深克隆
浅克隆与深克隆的区别

JAVA将数据类型分为基本数据类型以及引用数据类型,我认为浅克隆与深克隆的区别主要在于对引用类型的成员属性的操作。深度克隆应该递归克隆引用类型的成员属性。

浅克隆实现
  • 实现Cloneable接口
  • 重写clone方法,调用父类的clone方法

代码

public class Text implements Cloneable{    private int age;    private Name name;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Name getName() {        return name;    }    public void setName(Name name) {        this.name = name;    }    @Override    protected Object clone(){        try {            return super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return null;    }}class Name{    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}public class Main {    public static void main(String[] args){        Name name1=new Name();        name1.setName("name1");        Text t1=new Text();        t1.setAge(12);        t1.setName(name1);        Text t2=(Text) t1.clone();        System.out.println(t2.getName().getName());        name1.setName("name2");        System.out.println(t2.getName().getName());    }}复制代码

输出

name1name2复制代码

结果分析

因为只是直接调用父类的clone方法,没有对成员属性进行处理,所以在修改t1属性name的值时,t2属性name的值也会随之改变。

优点

简单易实现

缺点

无法真正克隆对象

深克隆实现
通过递归克隆实现

代码

public class Text implements Cloneable{    private int age;    private Name name;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Name getName() {        return name;    }    public void setName(Name name) {        this.name = name;    }    @Override    protected Object clone(){        Text text=null;        try {            text=(Text) super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }        text.setName((Name) text.getName().clone());        return text;    }}class Name implements Cloneable{    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    protected Object clone() {        try {            return super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return null;    }}复制代码

输出

name1name1复制代码
通过序列化实现

代码

public class Text implements Serializable{    private static final long serialVersionUID = 8723901148964L;    private int age;    private Name name;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public Name getName() {        return name;    }    public void setName(Name name) {        this.name = name;    }    public Object myClone(){        Text text=null;        ByteArrayOutputStream bos=new ByteArrayOutputStream();        try {            ObjectOutputStream oos=new ObjectOutputStream(bos);            oos.writeObject(this);            ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());            ObjectInputStream ois=new ObjectInputStream(bis);            text=(Text)ois.readObject();        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }        return text;    }}class Name implements Serializable {    private static final long serialVersionUID = 872390113109L;    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return name;    }}复制代码

输出

name1name1复制代码

结果分析

采用深克隆能有效隔离源对象与克隆对象的联系。

从实现过程来说,递归克隆存在克隆过程多且复杂的缺点,所以建议采用序列化的方式进行

深克隆。

总结

JAVA对象克隆共有两种形式,三种方法

  • 浅克隆
    • 调用clone方法
  • 深克隆
    • 递归调用clone方法
    • 序列化对象

三种方法之间互有优缺点,具体采用要根据实际情况。

转载于:https://juejin.im/post/5d0b50abe51d455d6d53583c

你可能感兴趣的文章
学习笔记——UNDO SEGMENT
查看>>
hessian 在PHP中的使用
查看>>
eclipse中一些常见svn图标的含义
查看>>
进度条(SeekBar和RatingBar)—Mars Android开发视频之第一季第十八集(重)
查看>>
Android6.0拨打电话时的权限问题
查看>>
华为SNS2124扩展端口授权及增加zone配置
查看>>
消息队列_RabbitMQ-0001.RabbitMQ消息代理/队列服务器快速安装部署?
查看>>
Linux crontab定时执行任务命令格式与详细例子
查看>>
服务器要使用两张网卡做bond0以实现网络冗余和提高带宽
查看>>
dhcp 配置
查看>>
中国孩子最需要的6种教育
查看>>
PVS让存储颤抖,系列博文之二:PVS的写缓存新技术之MCS方式实测篇
查看>>
jQuery插件开发的两种方法及$.fn.extend的详解
查看>>
SSDB高可用方案
查看>>
undo表空间
查看>>
Exchange 2013部署系列之(六)配置邮件流和客户端访问
查看>>
TE二次开发:点线面图层的结构
查看>>
关于swift的一些属性总结
查看>>
python学习笔记-Day17 (上节知识点补充)
查看>>
python学习笔记-Day04-第一部分(冒泡算法的实现)
查看>>