Java:浅克隆(shallow clone)与深克隆(deep clone)
2015-01-24 12:29
411 查看
Summary
浅克隆与深克隆对于JavaSE来说,是个难度系数比较低的概念,但不应该轻视它。
假设一个场景:对于某个list,代码里并没有任何对其的直接操作,但里面的元素的属性却被改变了,这可能就涉及到这个概念。
Description
浅克隆指仅copy对象位于栈内存中的引用(reference)。copy后,新旧两个引用指向同一个堆内存对象(即同一内存区域),但是堆内存中实际的对象copy前后均只有一个。使用"==" operator比较二者的地址会返回true。(不同引用,同一对象)
深克隆指则会copy一个新的对象并返回相应引用,即开辟了新的堆内存空间,因此使用“==” operator来比较两者的地址时会返回false。(不同引用,不同对象)
浅克隆(shallow clone)
clone对象是实例对象时,使用“=”操作符进行浅克隆。
clone对象是对象数组的元素时,使用
jdk中显式定义的clone操作基本上都使用:
例如ArrayList中的clone()、Arrays.copyOf()等对具体数组的clone其实底层都是调用该方法。
Click Me
操作说明:
创建一个ArrayList对象list0
list0中加入一个对象t
克隆list0对象为list1
再修改list0中元素(即t)的属性
结果说明:
ArrayList实现了Cloneable接口,arraylist.clone()为深克隆,故list0与list1分别指向不同内存区域。
ArrayList对象的clone()对于内部数组的元素仅为浅克隆,故list0中的元素(t)与list1中的元素为同一个,对list0元素的修改将影响到list1的元素。
浅克隆与深克隆对于JavaSE来说,是个难度系数比较低的概念,但不应该轻视它。
假设一个场景:对于某个list,代码里并没有任何对其的直接操作,但里面的元素的属性却被改变了,这可能就涉及到这个概念。
Description
浅克隆指仅copy对象位于栈内存中的引用(reference)。copy后,新旧两个引用指向同一个堆内存对象(即同一内存区域),但是堆内存中实际的对象copy前后均只有一个。使用"==" operator比较二者的地址会返回true。(不同引用,同一对象)
深克隆指则会copy一个新的对象并返回相应引用,即开辟了新的堆内存空间,因此使用“==” operator来比较两者的地址时会返回false。(不同引用,不同对象)
浅克隆(shallow clone)
clone对象是实例对象时,使用“=”操作符进行浅克隆。
clone对象是对象数组的元素时,使用
System.arraycoppy()进行浅克隆。(你非得要用"=" foreach地clone也没人拦着)
jdk中显式定义的clone操作基本上都使用:
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
例如ArrayList中的clone()、Arrays.copyOf()等对具体数组的clone其实底层都是调用该方法。
package com.scv.test.clone; import java.util.ArrayList; public class ArrayListCloneTest { public static void main(String[] args) throws Exception { CloneTarget t = new CloneTarget(); ArrayList<CloneTarget> list0 = new ArrayList<CloneTarget>(1); list0.add(t); ArrayList<CloneTarget> list1 = (ArrayList<CloneTarget>) list0.clone(); list0.get(0).setFieldA(20); System.out.println("0. " + (list0 == list1)); System.out.println("1. " + (list0.get(0) == list1.get(0))); System.out.println("2. " + list1.get(0).getFieldA()); } } class CloneTarget implements Cloneable{ private int fieldA = 10; @Override public CloneTarget clone() throws CloneNotSupportedException{ return (CloneTarget)super.clone(); } public void setFieldA(int a){ fieldA = a; } public int getFieldA(){ return fieldA; } } /* * Output: * 0. false * 1. true * 2. 20 */
Click Me
操作说明:
创建一个ArrayList对象list0
list0中加入一个对象t
克隆list0对象为list1
再修改list0中元素(即t)的属性
结果说明:
ArrayList实现了Cloneable接口,arraylist.clone()为深克隆,故list0与list1分别指向不同内存区域。
ArrayList对象的clone()对于内部数组的元素仅为浅克隆,故list0中的元素(t)与list1中的元素为同一个,对list0元素的修改将影响到list1的元素。
相关文章推荐
- java shallow clone(浅克隆)与深克隆(deep clone) 笔记
- JAVA中的深度克隆(deep clone) 和 影子克隆(shallow clone)浅析
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- Java Deep Clone Shallow Clone 深克隆和浅克隆
- java语言——对象的深复制(deep clone)与浅复制(shallow clone)
- Java Clone, Shallow Copy and Deep Copy
- Java中shallow clone 与deep Clone的区别
- Java中shallow clone 与deep Clone的区别
- java实现shadow clone(浅克隆)与深克隆(deep clone)
- java浅拷贝(shallow clone)与深拷贝(deep clone)
- java语言——对象的深复制(deep clone)与浅复制(shallow clone)
- java的对象克隆技术clone()之浅度克隆(shallow Clone)
- java实现shallow clone(浅克隆)与深克隆(deep clone)
- java实现深克隆(deep clone)
- Java中深拷贝(Deep Clone)与浅拷贝(Shallow Clone)
- Java克隆(Clone)的应用
- Java 克隆Clone 和 Apache BeanUtils
- java--为自己的类对象添加clone(克隆)能力
- Java中的克隆(Clone)机制
- Java克隆方法的研究(clone)