修改作为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
任何内容。