我们可以在 java 中使用引用传递吗?如果否 java.util.Arrays.sort 是如何工作的?

Can we use pass by reference in java? If No How does java.util.Arrays.sort works?

我曾经认为 Java 支持按值传递和按引用传递,但我遇到了很多讨论,例如

  1. Java is always pass by value, with no exceptions, ever .
  2. Java is always pass-by-value
  3. Java always passes arguments by value NOT by reference.
  4. Java passes references by value.So you can't change the reference that gets passed in.

如果java只支持按值传递
java.util.Array.sort()Collections.sort(unsortList)如何工作?

int iArr[] = {2, 1, 9, 6, 4};// sorting array

Arrays.sort(iArr);    

System.out.println("The sorted int array is:");
for (int number : iArr) {
    System.out.println("Number = " + number);
}

更新: 传递引用(按值)到底是什么意思?它与 C 或 C++ 中数组的引用传递行为有何不同?

更新: 如果我错了,请纠正我。在C中我们通过reference.In传递变量的地址Java我们传递对对象(或值)的引用。只要方法中的变量是指向Object的值对象随调用的方法中的变量而变化。 没有创建对象或引用的副本!,我只能看到 2 个不同的变量指向同一个对象,因为在 C++ 中通过 reference.Similar 通过引用传递两个不同的变量指向相同的地址。

数组是引用类型,因此 iArr 变量包含对数组的引用。

换句话说,当你调用

Arrays.sort(iArr);

您正在将引用(按值)传递给排序方法,该方法对 iArr 引用的数组进行排序。


来自评论:

What does passing a reference (by value) actually mean?

通过引用传递的意思是您基本上是将变量本身传递给方法。即,方法对变量所做的任何事情都会影响外部变量。 Java 中从来没有这种情况。 (尝试实现交换方法,您就会明白我的意思。)按值传递意味着您传递 存储在 变量中的值。在这种情况下,该值是一个引用,因此它按值传递一个引用。


回复。第二次更新:

从你的形象来看,我认为你已经很好地了解了情况,我认为这归结为术语。

如果我们暂时忘记 C++,它 真的 很简单。您需要记住的是 (A) 当您调用 method(var) 时,参数是 var 包含的任何内容的副本,并且 (B) 非原始变量的内容是一个引用 ( "pointer" 如果你愿意的话。

注意你的问题

int iArr[] = {2, 1, 9, 6, 4};

相当于

int[] iArr = new int[] { 2, 1, 9, 6, 4 };

所以这一切都检查出来了:iArr 持有一个参考和 new returns 一个参考。

当您调用 Arrays.sort(iArr) 时,将传递 iArr 的内容(即对数组的引用)。这仍然不是按引用传递,因为传递的是值,而不是变量本身。如果将方法内部的形式参数重新分配为指向其他数组,则 returns.

方法时 iArr 仍将指向原始数组

如果我们从C++的角度思考,事情往往会更复杂一些; C++ 的引用概念略有不同。使用 C++ 参考,您实际上可以实现真正的 swap:

void swap(int &x, int &y)
{
   int temp = x;
   x = y;
   y = temp;
}

即您可以传入 "a variable"(而不只是变量的内容)。我喜欢这样想,因为您正在与正在调用的方法共享变量的范围。这不能在 Java.

中完成

所以考虑到这一点,我会说 Java 引用更像 C++ 指针,除了它们的局限性在于你不能使用 * 运算符取消引用你可以在 C++ 中(你不能在 Java 中执行 *person,即使 person 存储对应于一个人的指针的内容)并且你无法获取对象的地址使用 & 运算符。你也不能做任何指针运算。例如,您不能执行 iArr + 3 来获取数组的第四个元素。

Java 支持按值传递 only.Its 不支持按引用传递。

看下面的代码:

 public static void main(String[] args) {
List l1 = new ArrayList(Arrays.asList(4,6,7,8));
System.out.println("Printing list before method calling:"+ l1);
foo(l1);
System.out.println("Printing list after method calling:"+l1);
}

public static void foo(List l2) {
l2.add("done"); // adding elements to l2 not l1
l2.add("blah");
}

看起来像按引用传递。但在内部仅按值工作。

输出:

Printing list before method calling:[4, 6, 7, 8]
Printing list after method calling:[4, 6, 7, 8, done, blah]

此示例与您的post 几乎相似。您正在将数组传递给 Arrays 方法,例如 Arrays.sort(iArr)。我正在将列表参数传递给我的方法 foo,即:foo(list1)

有关详细信息,请参阅 post

Java 总是使用按值传递。按值传递意味着 'value' 在传递时被复制。在传递对象时,被复制的 'value' 是对象的 'reference',而不是它自身的对象。因此,如果您要在方法内对对象进行更改,这些更改将在方法执行后得到反映。但是,例如将传递的 'reference' 设置为 'null' 将无效。

Java 始终是 按值传递 。 但是传递参数值取决于您传递的实体类型..

Primitives - 传递原始值。因此在调用方法中所做的更改不会影响调用方法中的原始值。

对象 - 传递指向对象的 内存地址 (即堆内存中的位置)。因此在调用方法中所做的更改反映在调用方法中。