修改作为method-parameter传递的数组

时间:2011-08-20 03:10:55

标签: java arrays clone pass-by-value

假设我有一个int数组,我想修改它。我知道我不能将新数组分配给作为参数传递的数组:

public static void main(String[] args)
{
    int[] temp_array = {1};
    method(temp_array);
    System.out.println(temp_array[0]); // prints 1
}
public static void method(int[] n)
{
    n = new int[]{2};
}

虽然我可以修改它:

public static void main(String[] args)
{
    int[] temp_array = {1};
    method(temp_array);
    System.out.println(temp_array[0]); // prints 2
}
public static void method(int[] n)
{
    n[0] = 2;
}

然后,我尝试使用clone()

将任意数组分配给作为参数传递的数组
public static void main(String[] args)
{
    int[] temp_array = {1};
    method(temp_array);
    System.out.println(temp_array[0]); // prints 1 ?!
}
public static void method(int[] n)
{
    int[] temp = new int[]{2};
    n = temp.clone();
}

现在,我想知道为什么它在上一个例子中打印1,而我只是用clone()复制数组,它只是复制值而不是引用。你能帮我解释一下吗?


编辑:有没有办法将数组复制到对象而不更改引用?我的意思是打印最后一个例子2

4 个答案:

答案 0 :(得分:4)

在你的方法中

public static void method(int[] n)

n是传入方式的数组的另一个名称。它指向内存中与原始数据相同的位置,即原始数组。如果更改存储在该数组中的某个值,则指向该数组的所有名称都将显示更改。

然而,在实际方法中

public static void method(int[] n) {
    int[] temp = new int[]{2};
    n = temp.clone();
}

您正在创建一个新数组,然后说“名称'n'现在指向此处,其他数组,而不是传入的数组”。实际上,名称“n”不再是传入的数组的名称。

答案 1 :(得分:4)

您的示例1和3在问题的上下文中几乎相同 - 您正在尝试为n分配一个新值(这是对通过值传递的数组的引用)。

您克隆temp数组这一事实并不重要 - 它所做的只是创建temp的副本,然后将其分配给n

为了将值复制到传递到method方法的数组中,您可能需要查看:System.arraycopy

当然,这一切取决于n数组的大小以及您在method方法中创建的数组。

假设它们都具有相同的长度,例如,您可以这样做:

public static void main(String[] args)
{
    int[] temp_array = {1};
    method(temp_array);
    System.out.println(temp_array[0]);
}
public static void method(int[] n)
{
    int[] temp = new int[]{2};
    System.arraycopy(temp, 0, n, 0, n.length); 
    // or System.arraycopy(temp, 0, n, 0, temp.length) - 
    // since we assumed that n and temp are of the same length
}

答案 2 :(得分:1)

正如您所正确注意的那样,您无法分配作为参数传递的数组引用。 (或者更准确地说,分配对调用者没有任何影响。)

这是你能做的最好的事情:

public static void method(int[] n) {
    int[] temp = new int[]{2};
    for (int i = 0; i < temp.length; i++) {
        n[i] = temp[i];
    }
    // ... or the equivalent using System.arraycopy(...) or some such
}

当然,只有输入数组的大小与要复制到的数组的大小相同时,才能正常工作。 (你应该如何处理这个将是特定于应用程序...)


对于记录,Java按值传递数组引用。它不会按值传递数组内容。而克隆将无助于解决这个问题。 (至少,不是声明的方法签名。)

答案 3 :(得分:0)

method方法中,您分配给n的任何内容都不会更改传入并分配给n的对象的值。在method开始时,n指向数组。当您将n分配给另一个数组时,您只需重新指向哪个数组n指向temp_array方法中的main的任何内容都没有改变