Java数组按引用传递不起作用?

33

我以为几乎所有编程语言,包括Java,都是将数组作为引用(可修改的)传递给函数。

但在此情况下却不起作用,testArray仍然是1,2,3,大小为3。

奇怪的是,当我将result[i] = 2更改为a[1] =2时,它就可以工作了。 它确实通过引用传递。

这段代码有什么问题?

最后,我使用了a = result; (更新了a)。结果是否从栈中删除了?这就是为什么我仍然得到原始的a吗?

我很困惑。

谢谢!

class Test
{
   public static void main(String[] args)
   {

      int[] testArray = {1,2,3};
      equalize(testArray, 6);

      System.out.println("test Array size :" + testArray.length);
      for(int i = 0; i < testArray.length; i++)
         System.out.println(testArray[i]);
   }

   public static void equalize(int[] a, int biggerSize)
   {
      if(a.length > biggerSize)
         throw new Error("Array size bigger than biggerSize");

      int[] result = new int[biggerSize];
     // System.arraycopy(a, 0, result, 0, a.length);
     // int array default value should be 0
      for(int i = 0; i < biggerSize; i++)
         result[i] = 2;

      a = result;
   }
}

请详细解释你的逻辑。你是想要扩大数组的大小吗?目前你的结果数组没有从原始数组中复制任何值。 - Sujee
你看过https://dev59.com/EXVD5IYBdhLWcg3wQJOT吗? - hejiaming007
8个回答

52
数组通过引用传递,但是该引用是按值传递的。也就是说,您可以更改 a 引用的数组,但不能更改 a 引用的是哪个数组

7

Java是按值传递的。这就是为什么你的代码不起作用的原因。一个好的实践是将int[] a标记为final,这样会导致编译错误(请参见相应的Checkstyle规则)。


5
从函数中返回参数"a"并赋值给主函数中的testArray。当您通过引用传递对象时,引用被复制并分配给函数。因此,该对象现在由2个引用引用。通过第二个引用对对象所做的任何更改都将反映在第一个引用中,因为它是两者引用的同一对象。但是,当您更改引用(而不是通过引用更改对象)时,情况就不同了。您已将第二个引用更改为指向另一个对象(int[] result)。因此,通过第二个引用进行的任何更改都只会更改“result”对象。
class Test
{
   public static void main(String[] args)
   {

      int[] testArray = {1,2,3};
      testArray = equalize(testArray, 6);

      System.out.println("test Array size :" + testArray.length);
      for(int i = 0; i < testArray.length; i++)
         System.out.println(testArray[i]);
   }

   public static int[] equalize(int[] a, int biggerSize)
   {
      if(a.length > biggerSize)
         throw new Error("Array size bigger than biggerSize");

      int[] result = new int[biggerSize];
     // System.arraycopy(a, 0, result, 0, a.length);
     // int array default value should be 0
      for(int i = 0; i < biggerSize; i++)
         result[i] = 2;

      a = result;
      return a;
   }
}

虽然可能吗,但是可以有void(或不返回任何内容)吗?谢谢。 - anon242463
新数组是在函数内部创建的,因此应该返回它。- 推荐的方法。 还有一些其他方法,例如在外部初始化结果数组并将其作为第三个参数传递,或者将第三个参数定义为Hashmap并将结果数组放入其中。 - Sujee


2

a 引用的数组可以被修改,但是引用本身是按值传递的。因此,如果你执行 a[0] = 1,那么你将更改原始数组。然而,a = result 更改了这个引用,因此原始引用保持不变。


有什么想法来实现我的函数吗?基本上我想将我的数组从3调整为6 :( - anon242463

1

1
我正在寻找的答案 - laycat

0
public class test
{
    public static void main(String[] args){
        int[] a = {15, 2, -3};
        printArray(a);
        changeArray(a);
        printArray(a);
    }
    private static void changeArray(int[] a){
        for(int i = 0; i < a.length; i++){
            a[i]++;
        }
    }

    private static void printArray(int[] a){
        for(int i = 0; i < a.length; i++){
            System.out.print(a[i] + " ");
        }
        System.out.println();
    }
}

-----输出-----

15 2 -3

16 3 -2


4
附加一些解释对于代码总是有益的。 - Richard Tingle

0

在Java中,数组是对象。如果您已经使用大小(实际长度)初始化了数组,则无法修改它。您可以创建一个具有不同大小的新数组(正如您当前在函数中所做的),并将所有值从旧数组复制到新数组中。在您的情况下,您有2个对象和3个引用。如果您想在调用函数中访问更大尺寸的数组,请使函数返回更大尺寸的数组的引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接