
在 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():
在创建 testArrays 对象时创建副本:
testArrays ta = new testArrays(Arrays.copyOf(arr1, arr1.length));
在 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 的引用传递机制对于编写健壮和可维护的代码至关重要。通过掌握创建对象副本的方法,可以避免意外修改原始数据,从而提高程序的可靠性。
以上就是Java 中对象数组的意外修改:引用传递与深拷贝的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号