Java函数在返回参数时是否复制参数传递的数组?
我读到了,它允许对其进行修改,这将反映在原始阵列上 我不确定上面链接中的引用部分,因为有人说,但是我确定修改参数数组也会改变原始数组 那么这是否意味着当我返回通过参数传递的相同数组时,Java将返回原始数组的副本?虽然不这样做,但使用原始阵列可以节省一些内存和CPU使用量?还是Java在这两种情况下都复制了数组 例如,以下两个功能相同还是第一个功能节省内存和cpu资源Java函数在返回参数时是否复制参数传递的数组?,java,arrays,Java,Arrays,我读到了,它允许对其进行修改,这将反映在原始阵列上 我不确定上面链接中的引用部分,因为有人说,但是我确定修改参数数组也会改变原始数组 那么这是否意味着当我返回通过参数传递的相同数组时,Java将返回原始数组的副本?虽然不这样做,但使用原始阵列可以节省一些内存和CPU使用量?还是Java在这两种情况下都复制了数组 例如,以下两个功能相同还是第一个功能节省内存和cpu资源 public void modifyArray (int[] arr) { for (int i = 0; i <
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语句
你看,方法的调用方应该知道他在做什么。换句话说:他已经在向你传递一些数组;为什么您认为应该将其返回给他?这是否意味着返回的数组只是一个引用而不是数组副本?是的。如果你想复制,你需要自己复制。太棒了,我不想复制数组,只需要返回一个引用。