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

Posted

技术标签:

【中文标题】我们可以在java中使用引用传递吗?如果否 java.util.Arrays.sort 如何工作?【英文标题】:Can we use pass by reference in java? If No How does java.util.Arrays.sort works? 【发布时间】:2015-08-04 06:25:19 【问题描述】:

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

    Java is always pass by value, with no exceptions, ever . Java is always pass-by-value Java always passes arguments by value NOT by reference. 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中我们通过引用传递变量的地址。在Java中我们将引用传递给对象(或值)。只要方法中的变量指向对象,对象的值就会随着变量的变化而变化调用的方法。 没有对象或引用的副本!,我只能看到 2 个不同的变量指向与通过引用传递相同的对象。在 C++ 中类似,通过引用传递两个不同的变量指向相同的地址。

【问题讨论】:

我投票结束这个问题,因为问题中的链接答案已经回答了这个问题。 this问题的前三个答案。 它用详细的例子解释了你问题的第二部分。你有什么不明白的? 引用来自this 回答If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo 的评分最高的答案。这解释了按值传递与按引用传递有何不同。引用第二个评分最高的答案:myDog still has the value 42; it's still pointing to the original Dog (but note that because of line "AAA", its name is now "Max")。请解释一下您从答案中不明白的地方?他们回答你问什么。 我非常理解你的问题。不管你怎么说,java 都是按值传递的,如果你明白这意味着什么,你就不必问任何与 Java 中的引用如何工作有关的问题。 【参考方案1】:

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

换句话说,当你打电话时

Arrays.sort(iArr);

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


来自 cmets:

传递引用(按值)实际上意味着什么?

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


回复。第二次更新:

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

如果我们暂时忘记 C++,它真的很简单。您需要记住的是 (A) 当您调用 method(var) 时,参数是 var 包含的任何内容的副本,并且 (B) 非原始变量的内容是引用(“指针”如果你喜欢)。

请注意,在您的问题中

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

相当于

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

所以一切都检查出来了:iArr 持有一个引用,new 返回一个引用。

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

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

void swap(int &x, int &y)

   int temp = x;
   x = y;
   y = temp;

即您可以传入“变量”(而不仅仅是变量的内容)。我喜欢这样想,因为您正在与您正在调用的方法共享变量的范围。这不能在 Java 中完成。

因此,考虑到这一点,我会说 Java 引用更像 C++ 指针,只是它们在某种意义上受到限制,因为您不能像在 C++ 中那样使用 * 运算符取消引用(你可以' t 在 Java 中执行 *person,即使 person 存储与指向人的指针相对应的内容)并且您无法使用 & 运算符获取对象的地址。你也不能做任何指针算术。例如,您不能使用 iArr + 3 来获取数组的第四个元素。

【讨论】:

传递引用(按值)实际上意味着什么?它与 C 或 C++ 中数组的引用传递行为有何不同? 按引用传递 的意思是您基本上是将变量 传递给方法。即,该方法对变量所做的任何事情都会影响外部变量。在 Java 中情况并非如此。 (尝试实现swap 方法,您就会明白我的意思。)按值传递意味着您传递存储在变量中的值。在这种情况下,值是一个引用,所以它通过值传递一个引用。 支持@aioobe 评论,查看Why can't you swap in Java? @JishnuPrathap,不客气。我认为您所链接的问题中没有任何答案令人满意,但目前无法发布接近顶部的新答案。 Yes(但 C++ 引用仍然更强大,因为编译器在内部将使用 * 或那个指针,这在 Java 中无法实现)。【参考方案2】:

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

【讨论】:

如果不是因为 “当涉及到传递对象...”,我会赞成,因为对象一开始就没有被传递。如果您更新,请回复,以便我得到一个 ping。【参考方案3】:

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

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

Objects - 传递引用该对象的内存地址(即堆内存中的位置)。因此,在被调用方法中所做的更改会反映在调用方法中。

【讨论】:

通过说“但是传递参数值取决于你传递的实体的类型..”你只是在增加混乱!没有区别。在这两种情况下 都传递了原始值。因此,在被调用方法中所做的更改不会影响调用方法中的原始值。归结为解释iArr的“原始值”是对堆上某些东西的引用。不管方法做什么,都不能改变iArr的内容。【参考方案4】:

Java 仅支持按值传递。它不支持按引用传递。

查看以下代码:

 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]

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

查看帖子了解更多信息

Java pass by reference issue with List

【讨论】:

“即使我们在内部通过引用传递......”不,我们不是,说我们是只是令人困惑的事情。

以上是关于我们可以在java中使用引用传递吗?如果否 java.util.Arrays.sort 如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

Java的参数传递是「按值传递」还是「按引用传递」?

值传递和引用传递

Java参数传递到底是按 值传递 还是 引用传递 ?

我们不能使用通过引用“输出”传递的参数创建 SQL 服务器函数吗?

传递常量是通过引用自动传递的吗?

Java引用传递?值传递?