假设我有一个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
。
答案 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
的任何内容都没有改变