java的克隆
❶ java中对对象克隆,一定要实现Cloneable接口吗
是的。如果没渣知有实现Cloneable接口,则调用Object的clone方法克隆对象将会抛出下面这个错误:
CloneNotSupportedException
- 如果对象的类不支持 Cloneable 接口,则重写 clone
方法的子类也会抛出此异常,以指示无法复制某胡升个实例。裤梁老更多java技术请访问bug315。
这是Object中clone方法的定义:
protected Object clone() throws CloneNotSupportedException
❷ Java中将a对象转换为b对象及深复制的几种方式
在编程实践过程中,我们有时会遇到这样的需求:在某个时刻有一个对象A,其中已包含有效值,此时需要创建一个与A完全相同的新对象B,确保B的任何改动都不会影响到A中的值。这意 义是A与B是两个独立的对象,B的初始值由A对象确定。例如程序演示的情况:
结果:
>学生1:54321
>学生2:54321
为什么改变学生2的学号,学生1的学号也发生了变化呢?
原因在于(stu2 = stu1)。该操作将stu1的引用赋值给stu2,导致stu1和stu2指向内存堆中的同一对象。那么如何实现干净、清晰地复制一个对象呢?在Java中,仅使用简单的赋值语句无法满足这种需求,实现复制对象有多种方法:
(1)逐个属性赋值。
(2)重写java.lang.Object类中的方法clone()。
(3)使用org.apache.commons中的工具类BeanUtils和PropertyUtils进行对象复制。
(4)通过JSON之间的转换,进行对象克隆。
(5)通过序列化实现对象的复制。
接下来,我们将详细介绍其中的几种方法。
将A对象的值分别通过set方法加入B对象中
对属性逐个赋值,适用于属性较少的场景,操作较为直观。但对于属性较多的对象,这种方式会导致大量的get、set方法调用,操作变得繁琐。
重写java.lang.Object类中的方法clone()
介绍浅克隆和深克隆的概念。
浅克隆主要关注值类型的成员变量复制,而引用类型成员变量的引用地址保持不变。深克隆则会复制对象的引用类型成员变量,包括内部包含的对象。
浅克隆
实现步骤:被复制的类需要实现Cloneable接口,并覆盖clone()方法,使用super.clone()实现基本复制。
结果展示:复制对象后,如果成员变量为引用类型,新对象与原对象引用同一内存地址。
深克隆
完整代码实现深克隆,解决浅克隆的局限性。
结果展示:无论成员变量是值类型还是引用类型,复制对象时均会复制所有的成员变量。
使用工具类BeanUtils和PropertyUtils进行对象复制
利用BeanUtils的Properties()方法将转换前的A类赋值给转换后的B类,简化属性复制过程。
注意点:属性名称需一致,B类存在A类不一定存在的属性,Spring的BeanUtils方法要求属性有getter和setter方法,且存在属性完全相同的内部类时,需特别注意。
通过JSON转换实现深克隆
利用fastjson进行对象与JSON串之间的转换,本质为反射操作。
通过序列化实现对象的复制
使用Java序列化机制,如SerializationUtils的clone()方法,要求对象实现Serializable接口。
总结与个人意见
在性能要求不高时,可选择简单、易于实现的方法如fastjson、序列化或DozerBeanMapper等。在性能要求较高的场景下,推荐自定义工具类实现更灵活的复制逻辑。