修改本地 vars 会在 vars 之外发生变化吗?
Modifying local vars changes outside vars?
我正在尝试了解以下 QuickSort 实现在 Java 中的工作原理。我已经掌握了大部分内容,但我很困惑它是如何做任何事情的。当你将一个变量传入一个函数并修改它时,它通常不会修改传入的原始变量。那么为什么这种没有return类型的快速排序的实现会修改传入的数组?
public static void quickSort(int[] arr, int low, int high) {
if (arr == null || arr.length == 0)
return;
if (low >= high)
return;
int middle = low + (high - low) / 2;
int pivot = arr[middle];
// make left < pivot and right > pivot
int i = low, j = high;
while (i <= j) {
while (arr[i] <pivot) {
i++;
}
while (arr[j] > pivot) {
j--;
}
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
if (low < j)
quickSort(arr, low, j);
if (high > i)
quickSort(arr, i, high);
}
因为数组被视为对象,在这种情况下,它们将引用的值传递给方法,这导致此实现对传递给此方法的数组起作用。
这和你做的一样
public void test(ObjectA obj) {
obj.setVal(1);
}
在这种情况下,您将处理传递的 ObjectA
并在此实例上调用方法 setVal
。在这种情况下,在方法 test
内部调用的方法也会反映此特定对象的传递实例内部的变化(因为它是同一个实例)。
数组也是如此
public static void main(String args[]) {
int[] arr = {1,2,3};
test(arr);
System.out.println(arr[0]); // This would print 13 now.
}
public static void test(int[] arr) {
arr[0] = 13;
}
如需进一步参考,您可以浏览 this question
您的 int[] arr
是对数组的引用。此引用是传递给它的引用的副本,不能更改该引用。但是,它引用的数组不会被复制,当您修改它时,调用者可以看到这些更改。
Java 中的所有内容均按值传递。如果我们谈论 non-primitives - 对象变量和数组,变量的 VALUE 是对象的 LINK。
我们不能 re-assign link,但我们可以更改对象的内部结构。
问题是,当我们传递基元时 - 它们保存在函数的 Stack 中,并且它们的更改不会影响方法调用中变量的值。
但是对象在堆中并且它们是共享的。所以我们可以从调用堆栈的任何地方更改它的内部结构。
我正在尝试了解以下 QuickSort 实现在 Java 中的工作原理。我已经掌握了大部分内容,但我很困惑它是如何做任何事情的。当你将一个变量传入一个函数并修改它时,它通常不会修改传入的原始变量。那么为什么这种没有return类型的快速排序的实现会修改传入的数组?
public static void quickSort(int[] arr, int low, int high) {
if (arr == null || arr.length == 0)
return;
if (low >= high)
return;
int middle = low + (high - low) / 2;
int pivot = arr[middle];
// make left < pivot and right > pivot
int i = low, j = high;
while (i <= j) {
while (arr[i] <pivot) {
i++;
}
while (arr[j] > pivot) {
j--;
}
if (i <= j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
}
if (low < j)
quickSort(arr, low, j);
if (high > i)
quickSort(arr, i, high);
}
因为数组被视为对象,在这种情况下,它们将引用的值传递给方法,这导致此实现对传递给此方法的数组起作用。
这和你做的一样
public void test(ObjectA obj) {
obj.setVal(1);
}
在这种情况下,您将处理传递的 ObjectA
并在此实例上调用方法 setVal
。在这种情况下,在方法 test
内部调用的方法也会反映此特定对象的传递实例内部的变化(因为它是同一个实例)。
数组也是如此
public static void main(String args[]) {
int[] arr = {1,2,3};
test(arr);
System.out.println(arr[0]); // This would print 13 now.
}
public static void test(int[] arr) {
arr[0] = 13;
}
如需进一步参考,您可以浏览 this question
您的 int[] arr
是对数组的引用。此引用是传递给它的引用的副本,不能更改该引用。但是,它引用的数组不会被复制,当您修改它时,调用者可以看到这些更改。
Java 中的所有内容均按值传递。如果我们谈论 non-primitives - 对象变量和数组,变量的 VALUE 是对象的 LINK。 我们不能 re-assign link,但我们可以更改对象的内部结构。
问题是,当我们传递基元时 - 它们保存在函数的 Stack 中,并且它们的更改不会影响方法调用中变量的值。 但是对象在堆中并且它们是共享的。所以我们可以从调用堆栈的任何地方更改它的内部结构。