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. 创建Activiti项目

    1.创建项目 2.导入Activiti的jar包 项目上右击创建lib文件夹 将jar包复制进lib文件夹 3.导入数据库连接jar包 4.使用代码创建Activiti用来存放流程数据的23张表 pa ...

  2. Swift入门篇-基本类型(3)

    一:元组 格式 变量或常量关键字 元组变量 = ( 变量,变量, …) 说明: : 元组变量还是一个变量,只不过表现方式和其他变量不一样 :()括号里面可以放入N个变量组成 例子: import Fo ...

  3. 更多文章请访问"程序旅途”

    更多文章请访问我的个人独立博客 程序旅途

  4. 深入分析Java Web技术(1)

    BS网络模型的基本过程: 当我们在浏览器中输入"www.google.com"的时候,首先会请求DNS服务器对域名进行解析成都应的IP地址,然后根据这个IP地址在互联网上找到谷歌的 ...

  5. mysql-5.7.15-winx64免安装版配置

    1.拷到硬盘根目录下; 2.在 bin 平行目录下新建  data 文件夹: 3. 修改  my-default.ini 文件,添加 basedir = C:\mysql-5.7.15-winx64d ...

  6. Pinterest 架构:两年内月 PV 从零到百亿【翻译】

    原文地址 这篇文章,采用 Markdown 方式,写的还是比较实在的,要是有架构图就好了. Pinterest 是图片版的 Twitter,用户把自己感兴趣的东西用图钉(Pins)钉在钉板(PinBo ...

  7. Mac OSX - 如何在bash_profile中配置全局环境变量

    我们知道,在Linux操作系统下,配置环境变量是使用如下命令: vim /etc/profile 在OSX下,我们用如下命令打开环境变量配置文件: open ~/.bash_profile 典型的环境 ...

  8. 简明易懂的call apply

    在iteye看到一篇对call解释得相当简明易懂,觉得得宣传一下 : http://uule.iteye.com/blog/1158829 一.方法的定义 call方法: 语法:call([thisO ...

  9. UiAutomator源代码分析之UiAutomatorBridge框架

    上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...

  10. eclipse 运行报java.lang.OutOfMemoryError: PermGen space解决方法

    一.在window下eclipse里面Server挂的是tomcat6,一开始还是以为,tomcat配置的问题,后面发现,配置了tomcat里面的catalina.bat文件,加入 set JAVA_ ...