在需要操作对象副本而保留原对象完整性的场景下,可采用Java的克隆机制。但使用时必须理解其底层原理,谨慎处理,避免因浅拷贝或引用问题导致数据异常,反而影响程序的正确性和稳定性。
1、 JDK中,Object类定义了clone方法,该方法为本地实现,其注释中特别强调:子类必须实现Cloneable接口才能调用此方法,否则将抛出异常。
2、 若类未实现Cloneable接口,在进行克隆操作时将抛出CloneNotSupportedException异常。
3、 编写测试类TestClone1验证该情况,运行结果证实会抛出异常。
4、 在Object类中,clone方法的定义为:protected native Object clone() throws CloneNotSupportedException。该方法被声明为受保护的本地方法,调用时可能抛出克隆不支持异常,表明其具体实现依赖于底层系统,且默认情况下并非所有对象都可被克隆。
5、 该方法使用protected修饰,仅允许自身及其子类访问,外部无法直接调用。
6、 完成浅层复制
7、 创建Bean1类,声明一个字符串类型的成员变量。
8、 创建Bean2类,实现Cloneable接口,包含一个基本类型变量i和一个引用类型变量bean1,并提供对应的get和set方法;重写clone方法,在方法中调用父类Object的clone方法,实现对象的克隆功能,确保能够复制当前对象的基本数据和引用对象。
9、 编写测试类TestClone2,创建Bean2对象t1并为其成员变量i和bean1设置值,通过t1克隆生成对象t2,随后对t1和t2的成员值进行比较,验证克隆后对象的状态是否一致。
10、 观察输出结果可见,t2与t1并非同一引用,t2的成员变量i已更新为10,符合预期。然而t2中的bean1与t1中的bean1指向同一对象,当通过t2修改bean1的str为xyx时,t1中的bean1也受到影响,内容同步改变,这充分说明了浅克隆仅复制对象本身,未对其引用类型成员进行深拷贝。
11、 实现深度克隆需对Bean2中引用的bean1属性进行复制,确保对象及其引用的子对象均独立存在。
12、 让Bean1实现Cloneable接口,覆盖clone方法,并调用Object类的clone方法来复制当前对象实例。
13、 修改Bean2中的clone方法,将bean1克隆得到的对象obj保存至变量t中。
14、 运行测试程序后发现,t2中的bean1与t1中的不同,修改t2中bean1的str值,对t1中的bean1无影响。
15、 实现对象深度克隆需让该对象实现Cloneable接口,并重写clone方法,确保对象及其引用的成员都被完整复制,从而完成一个完整的深拷贝过程。
16、 深度克隆是指对对象中每个引用类型属性逐层复制,确保所有嵌套的引用类型都被独立复制,从而实现完整的对象复制。
