Java的clone方法--深拷贝和浅拷贝
2017-08-17 20:16
239 查看
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:
clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException。Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例。
Object提供了一个对象拷贝的默认方法clone方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:
1、基本类型
如果变量是基本类型,则拷贝其值,比如:int、float、long等。
2、String字符串
这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为String是个基本类型。
3、对象
如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。
总结一下:
浅层复制: 被复制的对象的所有成员属性都有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅层复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深层复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不是原有的那些被引用的对象。换言之,深层复制要复制的对象 所引用的对象都复制一遍。
举个例子:
clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,否则会抛出CloneNotSupportException。Object中默认的实现是一个浅拷贝,也就是表面拷贝,如果需要实现深层次拷贝的话,必须对类中可变域生成新的实例。
Object提供了一个对象拷贝的默认方法clone方法,但是该方法是有缺陷的,它提供了一种浅拷贝方式,也就是它并不会把对象所有属性全部拷贝一份,而是有选择性的拷贝,拷贝规则如下:
1、基本类型
如果变量是基本类型,则拷贝其值,比如:int、float、long等。
2、String字符串
这个比较特殊,拷贝的是地址,是个引用,但是在修改的时候,它会从字符串池(String Pool)中重新生成新的字符串,原有的字符串对象保持不变,此处可以认为String是个基本类型。
3、对象
如果变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。
总结一下:
浅层复制: 被复制的对象的所有成员属性都有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅层复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深层复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不是原有的那些被引用的对象。换言之,深层复制要复制的对象 所引用的对象都复制一遍。
举个例子:
public class Client { public static void main(String[] args){ //定义父亲 Person p = new Person("父亲"); //定义大儿子 Person son1 = new Person("大儿子",p); //定义小儿子 Person son2 = son1.clone(); //重新给son2起名 son2.setName("小儿子"); //给小儿子,找个干爹 son2.getFather().setName("干爹"); System.out.println(son1.getName()+" 的父亲是 "+son1.getFather().getName()); System.out.println(son2.getName()+" 的父亲是 "+son2.getFather().getName()); } } class Person implements Cloneable{ private String name; private Person father; public Person(String name){ this.name=name; } public Person(String name,Person father){ this.name=name; this.father=father; } //拷贝的实现 @Override public Person clone(){ Person p = null; try{ //调用Object的浅拷贝 p = (Person) super.clone(); /** * 1.重新覆写对象实例部分的拷贝,实现深拷贝 * 2.如果没有重写对象实例部分的拷贝,那么大儿子和小儿子的父亲会引用同一个父亲, * 只要任意修改一下父亲,另外一个就会被修改 */ p.setFather(new Person(p.getFather().getName())); }catch(CloneNotSupportedException e){ e.printStackTrace(); } return p; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person getFather() { return father; } public void setFather(Person father) { this.father = father; } }
相关文章推荐
- Java中的clone方法之浅拷贝与深拷贝
- Java clone克隆方法 --深拷贝--浅拷贝 --原型模型
- Java clone方法深拷贝浅拷贝完全解析
- Java的clone方法--深拷贝和浅拷贝
- Java中的clone方法-深拷贝与浅拷贝
- Java中object的clone()方法的浅拷贝和深拷贝
- Java的一个高性能快速深拷贝方法。Cloneable?
- (3) java.lang.Object.clone()方法 以及 深拷贝浅拷贝 及其 实现
- java 重写接口Cloneable的Clone方法 拷贝对象
- 五星-原型模式常使用于以下场景--而JAVA中的任何类只要实现了Cloneable标识接口,就可以使用clone方法来进行对象的拷贝
- java数组的拷贝四种方法:for、clone、System.arraycopy、arrays.copyof
- java clone方法之深拷贝和浅拷贝
- java数组的拷贝四种方法:for、clone、System.arraycopy、arrays.copyof
- java中的clone()方法,浅拷贝和深拷贝
- java数组的四种拷贝方法的性能分析:for、clone、System.arraycopy、Arrays.copyof
- java clone()方法使用解析以及深/浅拷贝
- Java的一个高性能快速深拷贝方法。Cloneable?
- JAVA四种方法拷贝文件
- [置顶] C++/C#中堆栈、对象内存模型、深浅拷贝、Array.Clone方法
- java基础之对象的clone(深拷贝)