原文网址:http://blog.bd17kaka.net/blog/2013/06/25/java-deep-copy/

JAVA中的浅拷贝和深拷贝(shallow copy and deep copy)

一个示例

首先要区分”copy a value”和”copy an object”之间的区别:

  1. // copy a value
  2. int val = 1;
  3. int cpVal = val;
  4. // copy a value(the object reference for the array above)
  5. int[] val = new int[]{42};
  6. int[] cpVal = val;
  7. // copy a object
  8. StringBuffer object = new StringBuffer("I am a object");
  9. StringBuffer cpObject = new StringBuffer(object);

简单的说,赋值操作都是”copy a value”。如果想要”copy an object”,需要显式的或者在内部进行类似”new”的操作。

对象(object)的浅拷贝和深拷贝

浅拷贝意味着仅仅拷贝对象的一层,而深拷贝意味着拷贝对象多于一层的数据。那么问题就是,怎么去定义一层?

考虑下面的例子:

  1. public class Example {
  2. public int foo;
  3. public int[] bar;
  4. public Example() { };
  5. public Example(int foo, int[] bar) { this.foo = foo; this.bar = bar; };
  6. }
  7. Example eg1 = new Example(1, new int[]{1, 2});

下面两个例子分别执行了对eg1的浅拷贝和深拷贝

  1. Example eg2 = new Example(eg1.foo, eg1.bar);
  2. Example eg2 = new Example(eg1.foo, Arrays.copy(eg1.bar));

clone方法

每一个类和array都包含这个方法,它的功能是创建目的对象的一个拷贝,然而要注意以下几点:

  • deep无法确定到底是多少层?两层?三层?还是所有链接的对象
  • 实际上,文档并没有说明clone是否创建一个新的对象

下面是javadoc对于clone的解释:

  1. "Creates and returns a copy of this object.
  2. The precise meaning of "copy"
  3. may depend on the class of the object.
  4. The general intent is that, for any object x,
  5. the expression x.clone() != x will be true,
  6. and that
  7. the expression x.clone().getClass() == x.getClass()
  8. will be true,
  9. but these are not absolute requirements.
  10. While it is typically the case that
  11. x.clone().equals(x) will be true,
  12. this is not an absolute requirement."

Java List深拷贝实现

使用List的addAll方法就可以deep copy源列表中的所有元素(前提是list内部元素执行浅拷贝即可):

  1. public static void main(String[] args) {
  2. List<String> list = new ArrayList<String>();
  3. list.add("1");
  4. list.add("2");
  5. // 创建dest list,将源list的所有值都拷贝过去
  6. List<String> dest = new ArrayList<String>();
  7. dest.addAll(list);
  8. // 在dest list中添加一个元素,修改一个元素
  9. dest.add("3");
  10. dest.set(0, "2");
  11. // 打印两个数组
  12. for (String item : list) {
  13. System.out.println(item);
  14. }
  15. System.out.println("--------------------------------");
  16. for (String item : dest) {
  17. System.out.println(item);
  18. }
  19. System.out.println("--------------------------------");
  20. }

输出:

  1. 1
  2. 2
  3. --------------------------------
  4. 2
  5. 2
  6. 3
  7. --------------------------------

参考

Java :deep copy, shallow copy, clone

【转】JAVA中的浅拷贝和深拷贝的更多相关文章

  1. java中的浅拷贝和深拷贝

    复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...

  2. java中的浅拷贝与深拷贝

    浅拷贝: package test; class Student implements Cloneable { private int number; public int getNumber() { ...

  3. 【Java】 Java中的浅拷贝和深拷贝

    先抛出结论: 浅拷贝是引用拷贝,A对象拷贝B以后,A对象和B对象指向同一块内存地址,改变A对象的属性值会触发B对象属性的改变,有安全风险 深拷贝是对象拷贝,A对象拷贝B以后,A对象和B对象指向不同的额 ...

  4. 深入理解Java中的Clone与深拷贝和浅拷贝

    1.Java对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象. ...

  5. Java对象的浅拷贝和深拷贝&&String类型的赋值

    Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是 ...

  6. js中的浅拷贝和深拷贝

    说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...

  7. Javascript中的浅拷贝和深拷贝

    很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用 ...

  8. 浅谈JS中的浅拷贝与深拷贝

    前端工程师应该都比较熟悉浅拷贝和深拷贝的概念,在日常业务代码的过程中,特别是做数据处理的时候,经常行的会遇到,比如如何在不修改原对象的基础上,重新生成一个一模一样的对象,加以利用,又或是,如何巧妙地运 ...

  9. javascript中的浅拷贝和深拷贝(拷贝引用和拷贝实例)

    作者:千锋教育链接:https://www.zhihu.com/question/23031215/answer/326129003来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

随机推荐

  1. matrix矩阵求逆 与解方程模板 留做备用 (有bug,待补充)

    // // main.cpp // 矩阵求逆 // // Created by 唐 锐 on 13-6-20. // Copyright (c) 2013年 唐 锐. All rights reser ...

  2. openstack手动部署简单记录

    1,关于网络规划部分,之前写的都好好的了,浏览器TM的崩溃了,我写几天的笔记 记录全给我丢了,我TM的多心疼啊! 大致说了关于openstack手动安装关于网络规划的问题 第一种legacy netw ...

  3. windows 删除服务命令

    在dos窗口下执行 sc delete  服务名( 例如 mysql) C:\Program Files\MySQL\MySQL Server 5.6\

  4. <WinForm_1>初识WinForm编程

    暑假花了一个多月自学了Win32 SDK编程,不敢说成为了高手,但是还是颇具收获——windows的消息机制(著名的消息循环).一切控件均是窗口…… 曾经有一位网友(和我一个专业的)向我吐槽:Win3 ...

  5. Java[3] Java多线程相关资料

    Java多线程: http://www.uml.org.cn/j2ee/201509093.asp

  6. SEO名词_黒帽SEO

    一.什么是黒帽SEO 黑帽SEO是指通过一些操控和欺骗找寻搜索引擎漏洞的一些技术,让关键词排名在很短的时间获得非常好的排名的一项技术 二.黒帽SEO的危害 如果被搜索引擎识别网站采用的是黑帽SEO手段 ...

  7. [ES6] Promise

    How to use: export default function getReplies(topicId){ return new Promise(function( resolve, rejec ...

  8. Ubuntu 14.04 下手动安装Firefox的Flash插件

    有时候我们不得不採用手动安装一些软件. Ubuntu 14.04 下手动安装Firefox的Flash插件有下面几步 1. 下载Flash插件 下载地址为http://get.adobe.com/cn ...

  9. javascript sort 用法

    <html> <head> <title></title> <script type="text/javascript" sr ...

  10. Android-应用的本地化及知识拓展之配置修饰符

    步骤很简单,只需要两步: 1.创建带有目标语言的配置修饰符的资源子目录 2.将可选资源放入该目录下,android系统会自动处理后续工作 在这里我们需要讲解一下配置修饰符. 中文的配置修饰符:-zh, ...