首页 > 编程语言 >深入理解Java中的数组克隆:浅克隆与深克隆

深入理解Java中的数组克隆:浅克隆与深克隆

时间:2024-11-04 14:43:24浏览次数:1  
标签:Java 克隆 cloneMultiArr clone 999 multiArr 数组

深入理解Java中的数组克隆:浅克隆与深克隆

在Java编程中,数组的克隆是一个常见的需求,尤其是在处理复杂数据结构时。Java提供了数组的 clone 方法,但这个方法的行为在不同情况下有所不同。本文将通过一个具体的代码示例,深入探讨Java中数组的浅克隆和深克隆的概念,并解释它们之间的区别。

代码示例

package question1;

import java.util.Arrays;

public class Fpp {
    public static void main(String[] args) {
        int[][] multiArr = new int[2][3];        // (1)创建一个二维的int数组
        int[][] cloneMultiArr = (int[][]) multiArr.clone();
        // (2)让cloneMultiArr指向clone的数组
        cloneMultiArr[1][2] = 999;    // (3)给元素cloneMultiArr[1][2]赋值999
        System.out.println("multiArr[1][2]的值为:" + multiArr[1][2]); // (4)输出数组元素值
        System.out.println("cloneMultiArr[1][2]的值为:" + cloneMultiArr[1][2]);
        cloneMultiArr[1] = (int[]) multiArr[1].clone();    // (5)再次clone
        cloneMultiArr[1][2] = 777;            // (6)分别给两个数组的元素赋值
        multiArr[1][2] = 999;
        System.out.println("multiArr[1][2]的值为:" + multiArr[1][2]);// (7)输出数组元素值
        System.out.println("cloneMultiArr[1][2]的值为:" + cloneMultiArr[1][2]);
    }
}

代码分析

  1. 创建二维数组

    int[][] multiArr = new int[2][3];
    

    这里创建了一个 2x3 的二维数组 multiArr,所有元素初始化为 0

  2. 浅克隆二维数组

    int[][] cloneMultiArr = (int[][]) multiArr.clone();
    

    这里对 multiArr 进行浅克隆,cloneMultiArr 是一个新的二维数组,但它内部的每个一维数组仍然指向 multiArr 中的一维数组。

  3. 修改克隆数组的元素

    cloneMultiArr[1][2] = 999;
    

    这里修改了 cloneMultiArr[1][2] 的值为 999。由于浅克隆,cloneMultiArr[1]multiArr[1] 指向同一个一维数组,因此 multiArr[1][2] 也会被修改为 999

  4. 输出数组元素值

    System.out.println("multiArr[1][2]的值为:" + multiArr[1][2]); // 999
    System.out.println("cloneMultiArr[1][2]的值为:" + cloneMultiArr[1][2]); // 999
    

    由于浅克隆,两个数组的 [1][2] 元素都被修改为 999

  5. 再次克隆一维数组

    cloneMultiArr[1] = (int[]) multiArr[1].clone();
    

这里对 multiArr[1] 进行深克隆,cloneMultiArr[1] 现在指向一个新的独立的一维数组。这个新的数组是基于 multiArr[1] 的克隆,但它是一个全新的对象,与 multiArr[1] 完全独立。

  1. 分别修改两个数组的元素

    cloneMultiArr[1][2] = 777;
    multiArr[1][2] = 999;
    

    这里分别修改了 cloneMultiArr[1][2]multiArr[1][2] 的值。由于 cloneMultiArr[1] 现在是一个独立的一维数组,修改 cloneMultiArr[1][2] 不会影响 multiArr[1][2]

  2. 输出数组元素值

    System.out.println("multiArr[1][2]的值为:" + multiArr[1][2]); // 999
    System.out.println("cloneMultiArr[1][2]的值为:" + cloneMultiArr[1][2]); // 777
    

    由于深克隆,cloneMultiArr[1][2]multiArr[1][2] 现在是独立的,分别被修改为 777999

浅克隆与深克隆的区别

  • 浅克隆:只复制对象的基本结构,而不复制嵌套的对象。克隆对象中的引用类型字段仍然指向原始对象中的引用。
  • 深克隆:不仅复制对象的基本结构,还递归地复制所有嵌套的对象,生成全新的实例。

数组的 clone 方法

在Java中,数组的 clone 方法是一个浅克隆方法,但它对于一维数组来说,实际上是深克隆。这是因为数组的 clone 方法会创建一个新的数组对象,并将原始数组中的元素复制到新数组中。

为什么不需要实现 Cloneable 或序列化接口

  • 数组的 clone 方法:数组的 clone 方法是一个浅克隆方法,但它对于一维数组来说,实际上是深克隆。这是因为数组的 clone 方法会创建一个新的数组对象,并将原始数组中的元素复制到新数组中。
  • 不需要 Cloneable 接口:数组的 clone 方法是Java语言内置的,不需要实现 Cloneable 接口。
  • 不需要序列化接口:数组的 clone 方法不需要序列化接口,因为它直接在内存中进行复制操作。

通过这种方式,你可以直接使用数组的 clone 方法来实现深克隆,而不需要额外的接口或复杂的序列化操作。

总结

通过这个代码示例,我们可以清楚地看到浅克隆和深克隆的区别。浅克隆只复制对象的基本结构,而深克隆不仅复制基本结构,还递归地复制所有嵌套的对象。在处理复杂数据结构时,理解这两种克隆方式的区别非常重要,可以帮助我们编写出更健壮、更可靠的代码。

希望这篇博客能帮助你更好地理解Java中的数组克隆机制,并在实际开发中做出更合适的选择。如果你有任何问题或想法,欢迎在评论区留言讨论!

标签:Java,克隆,cloneMultiArr,clone,999,multiArr,数组
From: https://www.cnblogs.com/itcq1024/p/18525221

相关文章

  • C语言数组指针的使用学习笔记
    一、举例       intarr[5];               //arr是整型数组       int*parr1[10];       //parr1是整型指针数组        int(*parr2)[10]      //parr2是数组指针       int(*parr3[10])[5]  //par......
  • 说说Java的类加载机制?究竟什么是双亲委派模型?6B
    首先引入一个概念,什么是Java类加载器?一句话总结:类加载器(classloader)用来加载Java类到Java虚拟机中。官方总结:Java类加载器(英语:JavaClassloader)是Java运行时环境(JavaRuntimeEnvironment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中。类通常是按需加载,即第一次使......
  • 【JAVA】Java基础—Java概述:Java语言的历史与发展
    Java是一种广泛使用的编程语言,因其跨平台性、面向对象特性和强大的生态系统而受到开发者的青睐。Java最初由SunMicrosystems于1995年发布,经过多年的发展,已成为企业级应用、移动应用、Web开发和大数据处理等领域的主流语言。企业级应用:Java在大型企业应用中占据主导地位,特别......
  • 【JAVA】Java基础—Java概述:Java的特点
    Java语言因其独特的设计理念和强大的功能,在软件开发领域获得了广泛的应用。以下是Java的几个主要特点的详细说明,以及通俗易懂的例子来帮助理解这些概念。1.跨平台性理论说明Java的跨平台性是其最显著的特点之一,得益于Java虚拟机(JVM)的设计。Java程序在编译后生成字节码(.clas......
  • clean-code-javascript系列之并发
    使用Promises,不要使用回调回调不够简洁,因为他们会产生过多的嵌套。在ES2015/ES6中,Promises已经是内置的全局类型了,使用它们吧!不好的:require('request').get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin',(requestErr,response)=>{if(requestErr......
  • 关于工作中遇到的一些数组操作的小记
    1.Array对象如何转换成Object对象在JavaScript中,Array对象实际上已经是Object的一种特殊类型。Array继承了Object的所有属性和方法,所以你不需要转换Array对象到Object对象。不过,如果你想把Array对象转换为纯粹的Object对象,可以使用Object.assign()方法来实现......
  • Java & Collection/Executor & SynchronousQueue & 总结
    前言 相关系列《Java&Collection&目录》《Java&Executor&目录》《Java&Collection/Executor&SynchronousQueue&源码》《Java&Collection/Executor&SynchronousQueue&总结》《Java&Collection/Executor&SynchronousQueue......
  • java springboot对接微信小程序和微信支付v3接口
    1、controller代码packagecom.saburo.server.controller.weixin;importcn.dev33.satoken.annotation.SaIgnore;importcom.gcode.common.core.R;importcom.saburo.server.common.dto.WeiXinUserInfoDto;importcom.saburo.server.common.dto.money.PayDto;importcom.......
  • Java的泛型
    Java的泛型(Generics)是一种编程技术,它允许类、接口和方法在定义时使用参数化类型。通过泛型,可以编写更加通用和类型安全的代码。以下是Java泛型的一些关键知识点:1. 泛型类(GenericClass)定义泛型类时,使用尖括号 <> 来声明类型参数。例如:publicclassBox<T>{priva......
  • 泛型数组列表_演练
    ex1:基础练习基础练习请尽量独立完成(不要借助AI,实在不会才看参考代码)。原始数组学生类:packageex1;publicclassStudent{protectedStringname;protectedintscore;publicStudent(Stringname,intscore){this.name=name;this.sc......