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()方法中执行相应的深拷贝操作。

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

相关推荐
程序员清风8 小时前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林5519 小时前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
华仔啊14 小时前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing15 小时前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠1 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840821 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide1 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家1 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java
花花无缺1 天前
搞懂new 关键字(构造函数)和 .builder() 模式(建造者模式)创建对象
java
用户908324602731 天前
Spring Boot + MyBatis-Plus 多租户实战:从数据隔离到权限控制的完整方案
java·后端