即使在 void 函数中声明新变量也会产生副作用

Side-Effects Occurring Even When Declaring New Variables in Void Functions

我在做一个问题,我必须 return 输入数组的所有排列,我注意到一些非常奇怪的东西。出于这个问题的目的,我删除了代码中任何分散注意力的实际排列部分,以演示我在说什么。以下是代码:

public List<List<Integer>> permute(int[] nums) {
    permute(nums, 0);
    List<List<Integer>> output = new ArrayList<>();
    return output;
}

// Recursive void function.
private void permute(int[] nums, int index) {
    if (index > nums.length - 1)
        return;
    
    for (int i = 0; i < nums.length; i++) {
        int[] newNums = nums;  // Declare new array
        int newIndex = index;
        newNums[i] = -1;  // Modification on new array. 
        permute(newNums, newIndex + 1);
        print(nums); // Should technically show my "nums" without any side-effect as I've declared a new variable "newNums"
    }
}

// Simple function for printing out an array on the console.
private void print(int[] nums) {
    System.out.print("[");
    for (int num : nums) 
        System.out.print(num + ", ");
    System.out.print("]");
    System.out.println();
}

代码中有注释可以帮助您理解。如果我们输入 [1, 2, 3] 的数组 nums,我希望 print 方法打印一个不变的 nums [1, 2, 3] 数组。但是,它打印的是一个更改后的 nums 数组,其中包含 -1。

我知道 Java 中的 void 方法有副作用。但是,我的问题是,如果我在一个名为newNums.

 int[] newNums = nums;  // Declare new array

您已将 nums 引用分配给 newNums。执行该行后,nums 和 newNums 将指向同一个数组,因为它们具有相同的内存引用。当您通过分配 -1 修改 newNums 数组时,它也会反映到 nums 数组中,因为两者相同。
当您想将 nums 数组克隆到 newNums 数组中时,您可以执行如下操作。

  int [] newNums = nums.clone();

此行会将 nums 数组复制到新的内存位置,并且该内存位置将分配给新的 Nums 数组。