Java函数在返回参数时是否复制参数传递的数组?

Java函数在返回参数时是否复制参数传递的数组?,java,arrays,Java,Arrays,我读到了,它允许对其进行修改,这将反映在原始阵列上 我不确定上面链接中的引用部分,因为有人说,但是我确定修改参数数组也会改变原始数组 那么这是否意味着当我返回通过参数传递的相同数组时,Java将返回原始数组的副本?虽然不这样做,但使用原始阵列可以节省一些内存和CPU使用量?还是Java在这两种情况下都复制了数组 例如,以下两个功能相同还是第一个功能节省内存和cpu资源 public void modifyArray (int[] arr) { for (int i = 0; i <

我读到了,它允许对其进行修改,这将反映在原始阵列上

我不确定上面链接中的引用部分,因为有人说,但是我确定修改参数数组也会改变原始数组

那么这是否意味着当我返回通过参数传递的相同数组时,Java将返回原始数组的副本?虽然不这样做,但使用原始阵列可以节省一些内存和CPU使用量?还是Java在这两种情况下都复制了数组

例如,以下两个功能相同还是第一个功能节省内存和cpu资源

public void modifyArray (int[] arr)
{
    for (int i = 0; i < arr.length; i++) arr[i] = i + 1;
}

public int[] modifyArray (int[] arr)
{
    for (int i = 0; i < arr.length; i++) arr[i] = i + 1;
    return arr;
}
public void modifyArray(int[]arr)
{
对于(int i=0;i
编辑:


更清楚地说,我只关心性能(特别是在处理大型阵列时),实际上我不需要复制阵列,我有一个执行此操作的现有代码,我想知道删除retun部分是否会提高性能。

Java按值传递引用。这意味着更换阵列不会造成任何伤害,即

public void f(String[] a)
{
   a = new String[42];
}

但更改其中的任何内容都会更改原始数组。一般对象的深度复制可能非常耗时,而且在对象包含引用对象的对象的情况下也很困难。。。因此标准行为是避免它。

这两个函数都修改传入的数组。值传递的是指向数组的指针,因此,当您对它所指向的基础数组进行操作时,您正在更改传入的数组。因此,第二个函数将在对其进行一些更改后返回传入的相同数组


现在,如果您将
arr=…
放在函数中的某个位置,然后对其进行处理,您将不会修改传入的数组,并且返回的内容将有所不同。这就是为什么有人说Java是按值传递的。只是在所有非原语情况下,值都是指针。

您提供的方法在某种程度上是相同的,它们都修改了作为参数传递的数组。返回数组时没有隐式深度复制

但是,返回深度副本的数组/集合或使其不可修改是一种很好的做法

您可以创建数组的副本,通过该副本应该是超快速的,或者在使用容器时,通过
Collections.unmodifiableList/Set/etc()创建一个不可修改的包装


注意:这仅适用于容器的“1D”,如果您有n维数组或容器,则需要进行深度复制。

每个primitve在Java中按值传递

看看这个例子:

public void test2(int s) {
    s = 2;
    System.out.println(2);
}
如果您运行它:

int k = 5;
reporter.test2(k);
System.out.println(k);
Java将按值传递s。它不会影响原始值。 k的输出仍然是5

对于对象,它总是按值引用。它传递对原始值的引用并对其进行修改


回答您的问题-在第二个示例中,您只需返回对原始数组的引用。无论是否返回引用,原始引用都会受到影响(因为数组是对象)。

您可以这样做;让方法返回作为参数传递给该方法的相同数组

但这使得该方法的“接口”更难理解

换句话说:除非我们讨论的是真正的大数组;或者每秒调用数百次的方法;然后你应该专注于清晰易读的代码,这不会让读者感到惊讶;而不是无缘无故地添加return语句


你看,方法的调用方应该知道他在做什么。换句话说:他已经在向你传递一些数组;为什么您认为应该将其返回给他?

这是否意味着返回的数组只是一个引用而不是数组副本?是的。如果你想复制,你需要自己复制。太棒了,我不想复制数组,只需要返回一个引用。