Java中对象的赋值分为浅拷贝和深拷贝

1.对象浅拷贝

public class CloneTest{
    static class Emp{
        String name;
        int age;
        Date hireDate;
    }
    public static void main(String[] args){
        Emp emp1=new Emp();
        Emp emp2=emp1;
    }
}

这种用“=”赋值的情况下就是对象的浅拷贝。在内存中emp1和emp2都指向java堆中同一个对象(如果虚拟机让引用直接存储的是对象的地址的话就指向同一块内存地址,如果引用存储的是一个句柄的话,就指向同一个句柄)。

在这种情况下,无论我们修改的是emp1还是修改emp2都会在另一个引用中表现出来。可是在通常情况下我们想得到这样的一个对象:和原来对象一样但又不是同一个。这是我们就得使用对象克隆。

2.对象深拷贝

2.1对象克隆

一个对象能被克隆的前提是它必须继承Cloneable接口。该接口没有包含任何内容只是一个标记,表示该类的所有对象可以被克隆。然后使用public修饰符重新定义clone方法,因为,clone方法在Object类中被定义为protected,它默认也是浅拷贝。

protected native Object clone() throws CloneNotSupportedException;

在覆写该clone方法时可以使用协变技术让clone类返回特定的类型。

public class Emp implements Cloneable{
    private String name;
    private int age;
    private Date hireDate;    

    @Override
    protected Emp clone() throws CloneNotSupportedException {
        Emp emp =(Emp)super.clone();
        emp.hireDate=(Date)hireDate.clone();
        return emp;
    }
}

在这里我们看到,Date类可以调用clone方法没有出错是因为Date类继承了Cloneable接口。

public class Date implements java.io.Serializable, Cloneable, Comparable<Date>

但是当我们类中使用的一个组件它并没有继承Cloneable接口时我们该怎么办?还有一个问题是使用clone方法就得是与该对象有关的对象链上的所有对象都继承Cloneable接口。这未免有些太麻烦,况且一个类在设计的时候不知道他是否要被克隆,难道当你需要克隆的时候通知那个类的程序员让他给类添加Cloneable继承?这显然是不合理的。因此,这种使用clone方法实现对象的深拷贝不建议使用

2.2对象序列化方式实现深拷贝

关于对象序列化请移步这里。

只要对应的类是可序列化的即可。其做法很简单:直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对现有对象的一个深拷贝。在此过程中,我们不必将对象写出到文件中,因为可以用ByteArrayOutputStream将数据保存到字节数组中。

public class SerialCloneable implements Cloneable,Serializable {
    private static final long serialVersionUID = 7403553044775279221L;
    public Object clone() {
        try {
            //save the object to a byte array
            ByteArrayOutputStream bout=new ByteArrayOutputStream();
            ObjectOutputStream out= new ObjectOutputStream(bout);
            out.writeObject(this);
            out.close();
            // read clone of the object from the byte array
            ByteArrayInputStream bin= new ByteArrayInputStream(bout.toByteArray());
            ObjectInputStream in=new ObjectInputStream(bin);
            Object ret=in.readObject();
            in.close();
            return ret;
        } catch (Exception e) {
            return null;
        }
    }
}

更简单的方法,想要得到clone,只需要扩展SerialCloneable类,这样就完事了。但是应当慎用,因为它通常会比显示地构建对象并复制或克隆数据域的克隆方法慢得多。

Java对象的复制的更多相关文章

  1. java对象深复制、浅复制(深拷贝、浅拷贝)的理解

    先看一个例子 User user1 = new User(); user1.setId("111"); Map<String, User> map1 = new Has ...

  2. Java——对象的复制、克隆、序列化

    原创作者: https://blog.csdn.net/lmb55/article/details/78277878对象克隆(复制)假如说你想复制一个简单变量.很简单: int apples = 5; ...

  3. java对象克隆复制

    原文链接:https://blog.csdn.net/ztchun/article/details/79110096 自己先简单描述总结一下:当想要将一个对象中已有的值直接给另外一个对象的时候,其实并 ...

  4. java 对象属性复制,将一个对象的属性值赋值给另一个对象, 属性名需要相同

    import org.springframework.beans.BeanUtils; BeanUtils.copyProperties(源对象, 目标对象);

  5. JAVA对象转换JSON

    1. 把java 对象列表转换为json对象数组,并转为字符串 复制代码 代码如下: JSONArray array = JSONArray.fromObject(userlist); String ...

  6. Java 对象复制

    Java 对象的一共有 3 种复制对象的方式. 1.直接赋值 (引用复制 ),此种复制方式比较常用. 诸如 A  a = b ;  a 是直接复制了b的引用 ,也就是说它俩指向的是同一个对象. 此时 ...

  7. Java学习笔记之对象的复制和克隆

    假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...

  8. Java对象和集合的拷贝/克隆/复制

    昨天同事遇到了一个奇怪的问题,他需要将一个JavaBean拷贝一份,然后对新创建的Bean进行操作.但是他对新的Bean操作后,会影响旧的Bean的值.当听到这个问题的时候,我第一反应就是他的拷贝方法 ...

  9. java复制对象,复制对象属性,只可复制两个对象想同的属性名。也可自定义只复制需要的属性。

    注意:使用时copy()方法只会复制相同的属性.常用的copy()方法.以下为封装的工具和使用方式. 1.封装类 import java.util.Map; import java.util.Weak ...

随机推荐

  1. 关于PF_RING/Intel 82599/透明VPN的一些事

    接近崩溃的边缘,今天这篇文章构思地点在医院,小小又生病了,宁可吊瓶不吃药,带了笔记本却无法上网,我什么都不能干,想了解一些东西,只能用3G,不敢 开热点,因为没人给我报销流量,本周末我只有一天时间,因 ...

  2. 用Pomelo 搭建一个简易的推送平台

    前言 实际上,个人感觉,pomelo 目前提供的两个默认sioconnector和hybridconnector 使用的协议并不适合用于做手机推送平台,在pomelo的一份公开ppt里面,有提到过, ...

  3. 泛型baseDaoImpl类中如何知道具体子类的class类型

    package com.atguigu.surveypark.dao.impl; import java.lang.reflect.ParameterizedType; import java.uti ...

  4. 基于Qt的遥感图像处理软件设计总结

     开发工具 VS2008+Qt4.8.0+GDAL1.9  要点 接口要独立,软件平台与算法模块独立,平台中各接口设计灵活,修改时容易. 设计软件时一步步来,每个功能逐一实现,某个功能当比较独立时可以 ...

  5. python 相关安装和配置

    永久链接: http://michaelzqm.iteye.com/blog/1841966 预览文章: python环境搭建   2013-04-04 博客分类: 综合   一. window环境安 ...

  6. Oracle Goldengate REPLICAT启动时报正在运行解决办法

    stop replicate时报ERROR: opening port for REPLICAT MYREP (TCP/IP error: Connection refused). start rep ...

  7. FoLlow 的技术博客

    酷壳 http://coolshell.cn 老赵点滴- 追求编程之美 http://blog.zhaojie.me/ Pixel-In-Gene Blog

  8. Python: 拷贝函数签名

    使用场景有很多,比如C API在Python下很多都变成了(*args, **kwargs)的参数,这时候可能需要为其添加一个更严格签名来约束参数. 查了许多资料,能有效的拷贝函数签名貌似只能通过动态 ...

  9. Servlet3.0学习总结——基于Servlet3.0的文件上传

    Servlet3.0学习总结(三)——基于Servlet3.0的文件上传 在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileu ...

  10. Java模式(适配器模式)【转载】

    转载地址: http://blog.csdn.net/elegant_shadow/article/details/5006175 今天看了下Java中的适配器模式,以下就来小做下总结和谈谈感想,以便 ...