new
一个对象和clone
一个对象的区别在于它们创建新对象的方式不同。
new
操作符用于创建一个新的对象实例。该操作会调用构造函数以初始化对象并分配所需的内存空间,返回指向该对象的引用。clone
方法是Object类中定义的一种浅拷贝操作方法。该方法使用当前对象的副本来创建一个新的对象,而无需调用任何构造函数,并将其返回给调用者。与new
不同的是,clone
创建的是原始对象的复制品。这个过程需要对象实现 Cloneable 接口(否则会抛出 CloneNotSupportedException 异常) 和覆盖 clone() 方法,以便在运行时复制对象的所有字段。
因此,两者的主要区别在于,new
是通过构造函数显式地创建新对象;而 clone
是在运行时使用已有对象的克隆生成新对象,并且它可以避免构造器的执行。同时需要注意,clone
操作是一种浅拷贝,即只复制了对象的基本数据类型数据和对其他对象的引用(不复制其他对象),因此需要特别谨慎处理被克隆对象包含的有效性,防止意外修改原对象或错误使用新对象。
深入执行步骤
new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。
(根据new后的类型分配内存——>调用构造实例化——>发布引用地址)
clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。
(根据原对象的内存分配内存——>借用原对象的域为己所用——>发布引用地址)
除了创建新对象的方式不同之外,new
和 clone
还有以下使用细节上的区别:
-
new
用于创建一个全新的对象实例,而clone
则是通过复制一个已有对象来创建一个新的。具体地说,new
可以视为在内存中分配了一块新的空间,然后调用构造函数来初始化该空间以得到一个全新的对象实例;而clone
是对一个已经存在的对象,进行属性(浅拷贝)和方法的克隆,来得到一个新的对象副本。 -
使用时需要注意:
new
操作符在执行时会调用构造函数并分配内存空间;而clone
方法可能会在运行时抛出 CloneNotSupportedException 异常(如果相应类未实现 Cloneable 接口则会抛出此异常)。 -
关于对象属性的处理:
new
创建的对象可以根据构造函数参数设置相关属性的初值;而clone
仅能复制对象原始类型的数据和对其他对象的引用,浅拷贝不能充分地满足业务需求,通常需要进行深度克隆来使用。即需要对一些包含的对象单独进行 Clone 操作。
应用场景:
- 当需要创建一个新的完全独立的对象时,使用
new
。 - 当需要在已经存在的对象基础上创建一个新的对象副本,并且副本中需要复用部分原有对象的实例时,可以使用
clone
。如果需要深度克隆复杂的对象为完全独立的一个对象树时,则建议使用其他相关的工具类库。
总之, 二者应根据不同的场景进行选择和使用。 在Java中一些可变的集合类通过clone()方法定制出来的空间,可以提高效率和运行速度。而对于不可变对象的创建或一些快捷的对象创建需求,可以使用new。