【问题标题】:Java Two Dimensional Array passed to method and not changedJava二维数组传递给方法并且没有改变
【发布时间】:2015-05-01 05:40:50
【问题描述】:

这个关于将二维数组传递给方法的问题是在课堂上提出的。有人可以解释为什么在调用 doStuff() 后原始数组 d 没有变化吗?我调试了代码,发现该方法正在反转值,但是当返回时,原始数组保持不变。我认为将数组传递给一个方法并更改该方法中的值会影响原始数组。这里不是这样,原始数组没有改变。我的第一个想法是原来的会被颠倒过来。但是没有。

  1. 初始化数组 d 并调用 doStuff 为 如下:

        int d[][] = { {-1,0,1},  
                      {5,6,7},  
                      {2,3,4} };  
        doStuff(d);    
    
    
        public static void doStuff (int [][] frst)    
        {    
            int len = frst.length;    
            int sec[][] = new int[len] [];    
            for (int j=0; j<len; j++)  
            {        
                sec[j] = frst[len –j -1];     
            }       
            frst = sec;      
        }    
    

【问题讨论】:

  • java 是按值传递的,所以你需要返回值并将函数doStuff 的返回值再次赋值给变量d

标签: java arrays 2d


【解决方案1】:

Java 是按值传递的

返回您的值并将其设置为您的值。

        int d[][] = { {-1,0,1},
                      {5,6,7},
                      {2,3,4} };
        d = doStuff(d);


        public static int[][] doStuff (int [][] frst)
        {
            int len = frst.length;
            int sec[][] = new int[len] [];
            for(int j=0; j<len; j++)
                sec[j] = frst[len-j-1];
            return sec;
        }

}

您也可以直接设置传递的数组的值(数组变量是对数组的引用,因此编辑传递的数组引用的元素将起作用:

public static void doStuff (int [][] frst)
            {
                int len = frst.length;
                int sec[][] = new int[len] [];
                for(int j=0; j<len; j++)
                    sec[j] = frst[len-j-1];
                for(int j=0; j<frst.length;j++)
                    frst[j] = sec[j]
            }

【讨论】:

  • 这是有道理的,但我见过其他情况,其中只需更改方法中的值(对于数组或数组列表)就已经更改了没有返回语句的数组。这如何保持一致?
  • @BrettPenza 编辑以解决您的问题
【解决方案2】:

这里会发生什么。 创建了 2 个数组,initial 一个和 第二个,在 doStuff 方法中创建。

代码中有3个对数组的引用(变量):

  • 外部(用于方法):d

  • 内部:第一和第二。

在 doStuff 方法中,确实将 second 数组填充为完全没有更改的 initial 的反面。

在 doStuff 方法的末尾,firstsec 都引用了同一个对象,即 second 对象,而不是原始对象 - 因此你看到的行为

【讨论】:

    【解决方案3】:

    您已经有了一些很好的答案,但是这里有一些代码显示了这两种情况可能看起来不一致,但确实可以通过 java 是按值传递的事实来解释。棘手的一点是,对于数组,对数组的引用是按值传递的,而不是数组本身。

    因此,被调用函数接收到与调用函数相同的数组的引用副本,并且可以修改该数组中的元素。但是当被调用函数将引用本身修改为引用不同的数组时,它正在修改一个副本,这对调用者没有影响——也就是说,在调用者环境中,变量仍然在引用到原始数组。

    用方框和箭头更容易解释 :-),但希望下面的代码和输出会有所帮助:

    $ cat PBV.java
    class PBV
    {
        private static void modfiyArrayElement(int[] intArray) {
            // intArray is referring to the same array as in main
            intArray[0] = 17;
        }
    
        public static void main(String[] args) {
            int[] a = new int[]{ 1, 2, 3 };
            System.out.println(a[0]);
    
            modifyArrayElement(a);
            System.out.println(a[0]);
        }
    }
    
    $ java PBV
    1
    17
    
    $ cat PBV2.java
    class PBV2
    {
        private static void modfiyArrayReference(int[] intArray) {
            System.out.println("\nIn modifyArrayReference:");
            System.out.println("intArray[0] is " + intArray[0]);
            System.out.println("ref value of intArray is: " + intArray);
    
            intArray = new int[] { 100, 200, 300 };            
    
            // intArray is no longer referring to the same array as in main!
            // at this point munging with intArray won't have an effect in main
    
            System.out.println("\nintArray[0] is now " + intArray[0]);
            System.out.println("ref value of intArray is: " + intArray +"\n");
        }
    
        public static void main(String[] args) {
            System.out.println("in main:");
            int[] a = new int[]{ 1, 2, 3 };
            System.out.println("a[0] is " + a[0]);
            System.out.println("ref value of a is: " + a);
    
            modfiyArrayReference(a);
    
            System.out.println("back in main:");
            System.out.println("a[0] is still " + a[0]);
            System.out.println("ref value of a is still: " + a);
        }
    }
    
    $ java PBV2
    in main:
    a[0] is 1
    ref value of a is: [I@55a6c368
    
    In modifyArrayReference:
    intArray[0] is 1
    ref value of intArray is: [I@55a6c368
    
    intArray[0] is now 100
    ref value of intArray is: [I@37670cc6
    
    back in main:
    a[0] is still 1
    ref value of a is still: [I@55a6c368
    

    【讨论】:

      猜你喜欢
      • 2013-12-18
      • 1970-01-01
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      相关资源
      最近更新 更多