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

假设我有一个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

您的示例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 } 

在你的方法

 public static void method(int[] n) 

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

但是,在实际方法中

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

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

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

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

 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按值传递数组引用。 它不会按值传递数组内容。 而克隆将无助于解决这个问题。 (至少,不是声明的方法签名。)

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