【转】JAVA中的浅拷贝和深拷贝
原文网址:http://blog.bd17kaka.net/blog/2013/06/25/java-deep-copy/
JAVA中的浅拷贝和深拷贝(shallow copy and deep copy)
一个示例
首先要区分”copy a value”和”copy an object”之间的区别:
// copy a value
int val = 1;
int cpVal = val;
// copy a value(the object reference for the array above)
int[] val = new int[]{42};
int[] cpVal = val;
// copy a object
StringBuffer object = new StringBuffer("I am a object");
StringBuffer cpObject = new StringBuffer(object);
简单的说,赋值操作都是”copy a value”。如果想要”copy an object”,需要显式的或者在内部进行类似”new”的操作。
对象(object)的浅拷贝和深拷贝
浅拷贝意味着仅仅拷贝对象的一层,而深拷贝意味着拷贝对象多于一层的数据。那么问题就是,怎么去定义一层?
考虑下面的例子:
public class Example {
public int foo;
public int[] bar;
public Example() { };
public Example(int foo, int[] bar) { this.foo = foo; this.bar = bar; };
}
Example eg1 = new Example(1, new int[]{1, 2});
下面两个例子分别执行了对eg1的浅拷贝和深拷贝:
Example eg2 = new Example(eg1.foo, eg1.bar);
Example eg2 = new Example(eg1.foo, Arrays.copy(eg1.bar));
clone方法
每一个类和array都包含这个方法,它的功能是创建目的对象的一个拷贝,然而要注意以下几点:
- deep无法确定到底是多少层?两层?三层?还是所有链接的对象
- 实际上,文档并没有说明clone是否创建一个新的对象
下面是javadoc对于clone的解释:
"Creates and returns a copy of this object.
The precise meaning of "copy"
may depend on the class of the object.
The general intent is that, for any object x,
the expression x.clone() != x will be true,
and that
the expression x.clone().getClass() == x.getClass()
will be true,
but these are not absolute requirements.
While it is typically the case that
x.clone().equals(x) will be true,
this is not an absolute requirement."
Java List深拷贝实现
使用List的addAll方法就可以deep copy源列表中的所有元素(前提是list内部元素执行浅拷贝即可):
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
// 创建dest list,将源list的所有值都拷贝过去
List<String> dest = new ArrayList<String>();
dest.addAll(list);
// 在dest list中添加一个元素,修改一个元素
dest.add("3");
dest.set(0, "2");
// 打印两个数组
for (String item : list) {
System.out.println(item);
}
System.out.println("--------------------------------");
for (String item : dest) {
System.out.println(item);
}
System.out.println("--------------------------------");
}
输出:
1
2
--------------------------------
2
2
3
--------------------------------
参考
Java :deep copy, shallow copy, clone
【转】JAVA中的浅拷贝和深拷贝的更多相关文章
- java中的浅拷贝和深拷贝
复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...
- java中的浅拷贝与深拷贝
浅拷贝: package test; class Student implements Cloneable { private int number; public int getNumber() { ...
- 【Java】 Java中的浅拷贝和深拷贝
先抛出结论: 浅拷贝是引用拷贝,A对象拷贝B以后,A对象和B对象指向同一块内存地址,改变A对象的属性值会触发B对象属性的改变,有安全风险 深拷贝是对象拷贝,A对象拷贝B以后,A对象和B对象指向不同的额 ...
- 深入理解Java中的Clone与深拷贝和浅拷贝
1.Java对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象. ...
- Java对象的浅拷贝和深拷贝&&String类型的赋值
Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是 ...
- js中的浅拷贝和深拷贝
说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...
- Javascript中的浅拷贝和深拷贝
很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用 ...
- 浅谈JS中的浅拷贝与深拷贝
前端工程师应该都比较熟悉浅拷贝和深拷贝的概念,在日常业务代码的过程中,特别是做数据处理的时候,经常行的会遇到,比如如何在不修改原对象的基础上,重新生成一个一模一样的对象,加以利用,又或是,如何巧妙地运 ...
- javascript中的浅拷贝和深拷贝(拷贝引用和拷贝实例)
作者:千锋教育链接:https://www.zhihu.com/question/23031215/answer/326129003来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
随机推荐
- zabbix linux被监控端部署
测试使用agentd监听获取数据. 服务端的安装可以查看http://blog.chinaunix.net/space.php?uid=25266990&do=blog&id=3380 ...
- iperf网络测试工具
iperf https://sourceforge.net/projects/iperf/ http://downloads.es.net/pub/iperf/ https://github.com/ ...
- SpringMVC拦截器(实现登录验证拦截器)
本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...
- hdu 1331 Function Run Fun
Problem Description We all love recursion! Don't we? Consider a three-parameter recursive function w ...
- 魅蓝Note有几种颜色 魅蓝Note哪个颜色好看
http://www.pc841.com/shoujizhishi/39882.html http://news.mydrivers.com/1/359/359443.htm 魅族发布首款千元高性价比 ...
- 【IOS】IOS高速入门之OC语法
Objective-C 是 C 语言的超集 您还能够訪问标准 C 库例程,比如在stdlib.h和stdio.h中声明的那些例程. Objective-C 还是一种很动态的程序设计语言,并且这样的动态 ...
- Java 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
- Java 坦克小游戏心得
原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...
- vb.net转换为C#方法
第一个方法是上面有人说过的,用VB.NET TO C#的在线转换工具.既然你说不好用,那么可以这样:你把VB.NET代码编译了,然后用工具反编译(IL spy,reflector等)成C#代码.
- 生成getter()、setter()方法去掉变量前缀
当定义的变量名有前缀但是不想在生成它的getter()和setter方法的时候让前缀出现,比如今天项目的部分代码: public class Crime { private UUID mId; //标 ...