首页 > Java > java教程 > 正文

Java 中对象数组的意外修改:引用传递与深拷贝

花韻仙語
发布: 2025-09-01 21:04:22
原创
144人浏览过

java 中对象数组的意外修改:引用传递与深拷贝

在 Java 编程中,理解对象和数组的内存管理至关重要。一个常见的困惑是,当修改一个对象内部的数组时,有时会发现原始数组也发生了改变,这往往不是我们期望的结果。本文将通过一个具体的例子,深入探讨这个问题的原因,并提供解决方案。

问题分析:引用传递

在 Java 中,数组是一种对象。当我们创建一个数组并将其传递给一个对象时,实际上是将数组的引用传递给了该对象。这意味着对象和原始数组都指向内存中的同一个数组对象。因此,如果通过对象修改数组,实际上是在修改同一个内存区域,原始数组自然也会受到影响。

在提供的示例代码中:

public class testArrays {

    private int array1[] ;


    public testArrays(int[] arr) {
       this.array1 = arr;
    }

    public String toString(String name, int arr[]) {
           String outStr = "[";
           for (int i=0; i<= arr.length-1; i++) {
           if(i < arr.length-1)
              outStr = outStr + arr[i] + ", ";
           else
              outStr = outStr + arr[i] + "]";
           }
           return name + " = " + outStr;
    }

    public static void main(String[] args) {
        int arr1[] = {1, 2, 3, 4, 5, 6, 7};

        testArrays ta = new testArrays(arr1);

        System.out.println(ta.toString("arr1 Before ",arr1));
        System.out.println(ta.toString("ta.array1 Before ", ta.array1));

        ta.array1[2] = 333;

        System.out.println(ta.toString("arr1 After ",arr1));
        System.out.println(ta.toString("ta.array1 After ", ta.array1));
    }
}
登录后复制

arr1 和 ta.array1 都指向同一个数组对象。当执行 ta.array1[2] = 333; 时,实际上修改了该数组对象的第三个元素,因此 arr1 和 ta.array1 都会反映出这个变化。

立即学习Java免费学习笔记(深入)”;

解决方案:创建数组副本

要解决这个问题,我们需要确保对象拥有的是数组的副本,而不是原始数组的引用。这可以通过使用 Arrays.copyOf() 方法来实现。

Arrays.copyOf(int[] original, int newLength) 方法会创建一个新的数组,并将原始数组的内容复制到新数组中。newLength 参数指定新数组的长度。

有两种方式可以应用 Arrays.copyOf():

图改改
图改改

在线修改图片文字

图改改 455
查看详情 图改改
  1. 在创建 testArrays 对象时创建副本:

    testArrays ta = new testArrays(Arrays.copyOf(arr1, arr1.length));
    登录后复制
  2. 在 testArrays 类的构造函数中创建副本:

    public testArrays(int[] arr) {
        this.array1 = Arrays.copyOf(arr, arr.length);
    }
    登录后复制

无论选择哪种方式,都会创建一个新的数组对象,并将 arr1 的内容复制到新数组中。ta.array1 指向的是这个新数组,与 arr1 指向的是不同的数组对象。因此,修改 ta.array1 不会影响 arr1。

修改后的代码示例(使用构造函数创建副本):

import java.util.Arrays;

public class TestArrays { // 类名应以大写字母开头

    private int array1[] ;


    public TestArrays(int[] arr) {
       this.array1 = Arrays.copyOf(arr, arr.length);
    }

    public String toString(String name, int arr[]) {
           String outStr = "[";
           for (int i=0; i<= arr.length-1; i++) {
           if(i < arr.length-1)
              outStr = outStr + arr[i] + ", ";
           else
              outStr = outStr + arr[i] + "]";
           return name + " = " + outStr;
    }

    public static void main(String[] args) {
        int arr1[] = {1, 2, 3, 4, 5, 6, 7};

        TestArrays ta = new TestArrays(arr1);

        System.out.println(ta.toString("arr1 Before ",arr1));
        System.out.println(ta.toString("ta.array1 Before ", ta.array1));

        ta.array1[2] = 333;

        System.out.println(ta.toString("arr1 After ",arr1));
        System.out.println(ta.toString("ta.array1 After ", ta.array1));
    }
}
登录后复制

输出结果:

arr1 Before  = [1, 2, 3, 4, 5, 6, 7]
ta.array1 Before  = [1, 2, 3, 4, 5, 6, 7]
arr1 After  = [1, 2, 3, 4, 5, 6, 7]
ta.array1 After  = [1, 2, 333, 4, 5, 6, 7]
登录后复制

可以看到,arr1 的值没有受到影响,符合预期。

总结与注意事项

  • 引用传递: Java 中数组的传递是引用传递,这意味着多个变量可以指向同一个数组对象。
  • 深拷贝与浅拷贝: Arrays.copyOf() 创建的是数组的深拷贝,即创建了一个新的数组对象,并将原始数组的内容复制到新数组中。与此相对的是浅拷贝,它只复制对象的引用,而不复制对象本身。
  • 使用 Arrays.copyOf(): 当需要修改对象内部的数组,并且不希望影响原始数组时,应该使用 Arrays.copyOf() 创建数组的副本。
  • 命名规范: Java 编码规范建议类名以大写字母开头。在示例代码中,testArrays 应该修改为 TestArrays。

理解 Java 的引用传递机制对于编写健壮和可维护的代码至关重要。通过掌握创建对象副本的方法,可以避免意外修改原始数据,从而提高程序的可靠性。

以上就是Java 中对象数组的意外修改:引用传递与深拷贝的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号