Clone与New解析


对象创建的方式

  1. 使用new关键字
  2. 使用clone方法
  3. 反射机制
  4. 反序列化
  • 1、3方式会显示的调用对象的构造函数
  • 2是在在内存上对已存在的对象的一种引用,不会调用构造函数
  • 4是从文件中还原类的对象

clone:

  拷贝对象返还一个新对象,不是对源对象的引用,并且拷贝是对源对象的数据块的拷贝,包换源对象的信息,不是对象的初始信息,且不会调用构造函数。

  前提:类必须实现Cloneable接口,Cloneable接口是是一个空接口,实现了该接口才支持clone操作。

  疑问:既然Cloneable接口是空接口,且Java的对象中默认父类Object中也有clone方法,为什么还必须要实现该接口呢?

  这就是标志接口的意义,实现该接口,才能进行clone操作,因为JVM在clone对象时会检查该对象是否实现Cloneable接口,如果没有实现则会报CloneNotSupportedException异常。类似的接口还有Serializable接口,RandomAccess接口等。

  而拷贝也分深拷贝和浅拷贝。

public class user implement Cloneable{ 
    int age; //基本类型
    String name; //引用类型
}

 

  浅拷贝:是按位拷贝,会创建一个新的对象,对原有属性会有精确的拷贝,当数据类型是基本类型时,拷贝的是它的值,当属性是地址(引用类型)时,拷贝的是其内存地址,如果这个地址被其他对象改变了,也会影响到拷贝对象。而Object的默认clone实现就是浅拷贝。

  即上述类发生浅拷贝后,age属性值拷贝并分配新的内存,而引用类型String的name属性指挥拷贝其引用地址。

  深拷贝:会拷贝所有的属性值,并拷贝属性指向动态分配的内存当对象和所引用的对象一起拷贝时即发生深拷贝。深拷贝比浅拷贝速度慢,开销大。

  当上述类进行深拷贝后,age属性和name属性都将拷贝值并分配或指向新的内存。

new:

  jvm对new操作也有优化,轻量级对象使用new的速度回比clone快,但是复杂的对象,如在构造函数里面有复杂操作的,clone更快一点。