java中什么是深克隆和浅克隆?

在Java中,深克隆和浅克隆是涉及对象复制的两个概念。

  1. 浅克隆(Shallow Cloning):

    • 浅克隆创建一个新对象,该对象与原始对象具有相同的字段值。然而,对于对象内部的引用类型字段,浅克隆将复制引用而不是引用的内容。这意味着原始对象和克隆对象将共享相同的引用对象。
    • 在Java中,使用clone()方法来实现浅克隆。需要注意的是,被克隆的类要实现Cloneable接口,否则会抛出CloneNotSupportedException
    java 复制代码
    package javabasic;
    
    public class Style {
    
        private String color;
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    }
    java 复制代码
    package javabasic;
    
    public class Element implements Cloneable{
    
        private String name;
    
        private Style style; // 引用另一个对象
    
        public void init(String name, Style style){
            this.name = name;
            this.style = style;
        }
    
    	// 打印当前引用的style对象
        public void printStyle(){
            System.out.println(this.style);
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException{
            return super.clone();
        }
    }

    然后可以使用:

    java 复制代码
    package javabasic;
    
    public class Test {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Style style = new Style();
            style.setColor("#FF0000");
            
            Element original = new Element();
            original.init("rec",style);
            
            Element clone = (Element) original.clone();
            
            // 打印引用的对象style,可以看到是引用了同一个对象
            original.printStyle(); // javabasic.Style@4554617c
            clone.printStyle(); // javabasic.Style@4554617c
            
        }
    }
  2. 深克隆(Deep Cloning):

    • 深克隆创建一个新对象,并尽力复制原始对象及其所有嵌套的引用类型字段,以确保原始对象和克隆对象的内部对象不共享引用。
    • 实现深克隆可能涉及递归复制对象的内部引用。这可以通过手动实现clone()方法来实现,或者使用第三方库或序列化来处理。
    java 复制代码
    package javabasic;
    
    public class Style implements Cloneable{
    
        private String color;
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    java 复制代码
    package javabasic;
    
    public class Element implements Cloneable{
    
        private String name;
    
        private Style style; // 引用另一个对象
    
        public void init(String name, Style style){
            this.name = name;
            this.style = style;
        }
    
        // 打印当前引用的style对象
        public void printStyle(){
            System.out.println(this.style);
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException{
            Element clone = (Element)super.clone();
            // 对于引用类型字段,执行深拷贝
            clone.style = (Style) style.clone();
            return clone;
        }
    
    }
    java 复制代码
    package javabasic;
    
    public class Test {
    
        public static void main(String[] args) throws CloneNotSupportedException {
            Style style = new Style();
            style.setColor("#FF0000");
    
            Element original = new Element();
            original.init("rec",style);
    
            Element clone = (Element) original.clone();
    
            // 打印引用的对象style,可以看到是引用的是不同的对象
            original.printStyle(); // javabasic.Style@4554617c
            clone.printStyle(); // javabasic.Style@74a14482
    
        }
    }

    在这个例子中,Style 类也需要实现Cloneable接口,并在其clone()方法中执行相应的深拷贝操作。

请注意,手动实现深克隆可能会变得复杂,特别是当对象包含多层嵌套引用时。在某些情况下,使用序列化和反序列化,或者使用第三方库,可能是更简单和可靠的选择。

相关推荐
spencer_tseng18 小时前
Eclipse Uninstall Software
java·ide·eclipse
嗯、.18 小时前
使用 iText 9 为 PDF 添加文字水印的完整实战
java·pdf·itext
怪兽201418 小时前
缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题
java·缓存·面试
皮皮林55118 小时前
Java 25 正式发布:更简洁、更高效、更现代!
java
源码_V_saaskw19 小时前
JAVA国际版二手交易系统手机回收好物回收发布闲置商品系统源码支持APP+H5
java·开发语言·微信·智能手机·微信小程序·小程序
جيون داد ناالام ميづ19 小时前
Spring AOP核心原理分析
java·数据库·spring
霸道流氓气质19 小时前
SpringBoot+MybatisPlus+自定义注解+切面实现水平数据隔离功能(附代码下载)
java·spring boot·后端
海边夕阳200619 小时前
深入解析volatile关键字:多线程环境下的内存可见性与指令重排序防护
java·开发语言·jvm·架构
ZeroKoop19 小时前
JDK版本管理工具JVMS
java·开发语言
rengang6620 小时前
101-Spring AI Alibaba RAG 示例
java·人工智能·spring·rag·spring ai·ai应用编程