Java Object对象之clone方法
2016-11-28 00:00
176 查看
摘要: 克隆的目的:快速创建一个已有对象的副本。
参考:http://blog.csdn.net/bigconvience/article/details/25025561
克隆的步骤:
创建一个对象
将原有对象的数据导入到新创建的数据中
1. Object的clone()源代码简介
clone方法首先会判对象是否实现了Cloneable接口,若无则抛出CloneNotSupportedException, 最后会调用internalClone. intervalClone是一个native方法,一般来说native方法的执行效率高于非native方法。
当某个类要复写clone方法时,要继承Cloneable接口。通常的克隆对象都是通过super.clone()方法来克隆对象。
2.浅克隆(shadow clone)
克隆就是复制一个对象的复本.若只需要复制对象的字段值(对于基本数据类型,如:int,long,float等,则复制值;对于复合数据类型仅复制该字段值,如数组变量则复制地址,对于对象变量则复制对象的reference。
基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变c2实例对象中的属性就会影响。
深克隆(deep clone)
深克隆与浅克隆的区别在于对复合数据类型的复制。若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创建一个对象。
克隆方法用于创建对象的拷贝,为了使用clone方法,类必须实现java.lang.Cloneable接口重写protected方法clone,如果没有实现Clonebale接口会抛出CloneNotSupportedException.
在克隆java对象的时候不会调用构造器
java提供一种叫浅拷贝(shallow copy)的默认方式实现clone,创建好对象的副本后然后通过赋值拷贝内容,意味着如果你的类包含引用类型,那么原始对象和克隆都将指向相同的引用内容,这是很危险的,因为发生在可变的字段上任何改变将反应到他们所引用的共同内容上。为了避免这种情况,需要对引用的内容进行深度克隆。
代码:
下载地址: http://download.csdn.net/detail/meryhuang/9695751
参考:http://blog.csdn.net/bigconvience/article/details/25025561
克隆的步骤:
创建一个对象
将原有对象的数据导入到新创建的数据中
1. Object的clone()源代码简介
/** * Creates and returns a copy of this {@code Object}. The default * implementation returns a so-called "shallow" copy: It creates a new * instance of the same class and then copies the field values (including * object references) from this instance to the new instance. A "deep" copy, * in contrast, would also recursively clone nested objects. A subclass that * needs to implement this kind of cloning should call {@code super.clone()} * to create the new instance and then create deep copies of the nested, * mutable objects. * * @return a copy of this object. * @throws CloneNotSupportedException * if this object's class does not implement the {@code * Cloneable} interface. */ protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class doesn't implement Cloneable"); } return internalClone((Cloneable) this); } /* * Native helper method for cloning. */ private native Object internalClone(Cloneable o);
clone方法首先会判对象是否实现了Cloneable接口,若无则抛出CloneNotSupportedException, 最后会调用internalClone. intervalClone是一个native方法,一般来说native方法的执行效率高于非native方法。
当某个类要复写clone方法时,要继承Cloneable接口。通常的克隆对象都是通过super.clone()方法来克隆对象。
2.浅克隆(shadow clone)
克隆就是复制一个对象的复本.若只需要复制对象的字段值(对于基本数据类型,如:int,long,float等,则复制值;对于复合数据类型仅复制该字段值,如数组变量则复制地址,对于对象变量则复制对象的reference。
package haust.vk.demo; public class ShadowClone implements Cloneable{ private int a; // 基本类型 private int[] b; // 非基本类型 // 重写Object.clone()方法,并把protected改为public @Override public Object clone(){ ShadowClone sc = null; try { sc = (ShadowClone) super.clone(); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return sc; } public int getA() { return a; } public void setA(int a) { this.a = a; } public int[] getB() { return b; } public void setB(int[] b) { this.b = b; } }
package haust.vk.demo; public class App { public static void main(String[] args) throws CloneNotSupportedException{ ShadowClone c1 = new ShadowClone(); //对c1赋值 c1.setA(100) ; c1.setB(new int[]{1000}) ; System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]); //克隆出对象c2,并对c2的属性A,B,C进行修改 ShadowClone c2 = (ShadowClone) c1.clone(); System.out.println("克隆后c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); //对c2进行修改 c2.setA(50) ; int []a = c2.getB() ; a[0]=5 ; c2.setB(a); System.out.println("修改后c1: a="+c1.getA()+" b="+c1.getB()[0]); System.out.println("修改后c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); } }
基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变c2实例对象中的属性就会影响。
深克隆(deep clone)
深克隆与浅克隆的区别在于对复合数据类型的复制。若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创建一个对象。
public class DeepClone implements Cloneable { private int a; // 基本类型 private int[] b; // 非基本类型 // 重写Object.clone()方法,并把protected改为public @Override public Object clone(){ DeepClone sc = null; try { sc = (DeepClone) super.clone(); int[] t = sc.getB(); int[] b1 = new int[t.length]; for (int i = 0; i < b1.length; i++) { b1[i] = t[i]; } sc.setB(b1); } catch (CloneNotSupportedException e){ e.printStackTrace(); } return sc; } public int getA() { return a; } public void setA(int a) { this.a = a; } public int[] getB() { return b; } public void setB(int[] b) { this.b = b; } }
package haust.vk.demo; public class AppDeep { public static void main(String[] args) throws CloneNotSupportedException{ DeepClone c1 = new DeepClone(); //对c1赋值 c1.setA(100) ; c1.setB(new int[]{1000}) ; System.out.println("克隆前c1: a="+c1.getA()+" b="+c1.getB()[0]); //克隆出对象c2,并对c2的属性A,B,C进行修改 DeepClone c2 = (DeepClone) c1.clone(); System.out.println("克隆后c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); //对c2进行修改 c2.setA(50) ; int []a = c2.getB() ; a[0]=5 ; c2.setB(a); //基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变c2实例对象中的属性就会影响到c1 System.out.println("修改后c1: a="+c1.getA()+" b="+c1.getB()[0]); System.out.println("修改后c2: a="+c2.getA()+ " b[0]="+c2.getB()[0]); } }
克隆方法用于创建对象的拷贝,为了使用clone方法,类必须实现java.lang.Cloneable接口重写protected方法clone,如果没有实现Clonebale接口会抛出CloneNotSupportedException.
在克隆java对象的时候不会调用构造器
java提供一种叫浅拷贝(shallow copy)的默认方式实现clone,创建好对象的副本后然后通过赋值拷贝内容,意味着如果你的类包含引用类型,那么原始对象和克隆都将指向相同的引用内容,这是很危险的,因为发生在可变的字段上任何改变将反应到他们所引用的共同内容上。为了避免这种情况,需要对引用的内容进行深度克隆。
代码:
下载地址: http://download.csdn.net/detail/meryhuang/9695751
相关文章推荐
- Java Object对象之clone方法
- Java Object对象之clone方法
- Java Object对象之clone方法
- java Object对象的clone方法
- Flex RemoteObject 限制远程Java对象可访问方法
- Java-Object的clone方法 protected的相关问题。
- Java中的对象Object方法之---wait()和notifiy()
- (3) java.lang.Object.clone()方法 以及 深拷贝浅拷贝 及其 实现
- JAVA学习中,一个关于Object对象转换时对应方法的问题
- java-Object的clone()方法
- 我的Java开发学习之旅------>Java使用ObjectOutputStream和ObjectInputStream序列号对象报java.io.EOFException异常的解决方法
- Java中使用hql,sql查询返回的list<Object> 转成需要的实体对象--方法讲解!
- Java利用序列化实现对象深度clone的方法
- java中创建对象的几种方法和clone
- 为什么调用Object的clone方法却可以使得自己类中的对象被clone呢?
- Java中的对象Object方法之---wait()和notifiy()
- 面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆
- JAVA中Object对象拥有的方法
- Java 中 Object.clone() 方法以及protected 的一点思考
- Android进步之十四:使用jackon的ObjectMapper的writeValueAsString方法可以把java对象转化成json字符串