【问题标题】:Why is this void method not working as I would expect? [duplicate]为什么这个 void 方法没有像我预期的那样工作? [复制]
【发布时间】:2015-06-08 01:59:38
【问题描述】:

假设给定数组实例化如下: int[] 给定 = {1, 2, 3, 4, 5};

这些方法应该改变数组并显示打印结果。

public int[] change(int[] given) {
   out.println(Arrays.toString(given)); //before-changes
   whatIsGoingOn(given); //make changes
   out.println(Arrays.toString(given));//after changes
   return given; //return the supposedly changed array
}
//Make changes:
public void whatIsGoingOn(int[] given) {
   given = new int[5];
   given[0] = 200;
}

我认为问题在于 void 方法,它会覆盖给定 int[] 的原始值,但新的初始化和声明永远不会出现。

我希望数组是:

{200, 0, 0, 0, 0};

但是 Java 会打印出来:

{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}

但在我在 whatIsGoingOnMethod 中返回一个新更改的数组的情况下,我得到了我想要的结果:

{1, 2, 3, 4, 5}
{200, 0, 0, 0, 0}

如果 void 方法只是做了一些事情并且它并没有像我期望的那样真正被“应用”。对此我将不胜感激。

这个问题已经回答了,谢谢!!! 我需要冷冻它。

【问题讨论】:

标签: java arrays void


【解决方案1】:

使用given = new int[5];,您正在更改给定的局部变量指向的内容,而不是它曾经指向的对象。本地后来超出范围。数组永远不会被修改。

您正在创建一个全新的数组,并将用于引用原始数组的变量分配给新数组。您正在修改新数组,而永远不会触及旧数组。

适当的修复将类似于以下内容:

public static void main(String[] args)
{
    int[] original = new int[5];//already allocating memory, initializing to default value, etc.
    setFirstTo20(original);
    System.out.println(original[0]);//still 20!
}

public static void setFirstTo20(int[] given)
{
    for (int i : given)
        System.out.println(i);//for debugging, before change
    given[0] = 20;
    for (int i : given)
        System.out.println(i);//after change
    //heres whats happening to you
    given = new int[5];
    given[0] = 40;
    for (int i : given)
        System.out.println(i);//show new changes to NEW array
}

如果您打算在实际类中使用此方法或类似方法,显然您应该删除无关代码。

【讨论】:

  • 所以在 void 方法内部,数组被改变了,但是这些改变从来没有成功,是不是正确的?
  • 没有。您正在创建一个全新的数组,并将用于引用原始数组的变量分配给新数组。您正在修改新数组,而永远不会触及旧数组。我会用适当的修复来编辑我的答案。
  • @Will,Java 是按值传递的。如果它是通过引用传递的,那么您将获得 40。当您说 ` given = new int[5];` 时,您不再引用传递的原始given。在此之后对given 进行更改的任何行都不会被反映。
  • @我的更新是否有助于提供更清晰的理解?您应该考虑运行它来查看输出,以及使用调试器单步执行。
【解决方案2】:

因为函数whatIsGoingOn的参数given是按值传递的。 要在 void 函数中更改它,您必须将其包装在这样的对象中:

class ArrayRef {
    public int[] array;
}
public int[] change(int[] given) {
    out.println(Arrays.toString(given)); //before-changes
    ArrayRef ref = new ArrayRef();
    ref.array = given; //set a reference to the given array
    whatIsGoingOn(ref); //make changes
    given = ref.array; //get the changed array
    out.println(Arrays.toString(given));//after changes
    return given; //return the supposedly changed array
}
//Make changes:
public void whatIsGoingOn(ArrayRef ref) {
    ref.array = new int[5];
    ref.array[0] = 200;
}

【讨论】:

    【解决方案3】:

    int[] 等数组是引用类型。这意味着当您执行given = new int[5] 赋值时,您将链接whatIsGoingOn() 中引用的数组,而不影响change() 中引用的数组。

    要做你想做的事,你需要遍历数组并改变数组中的各个元素。

    for(int i = 0; i < given.length; i++) {
        given[i] = 0;
    }
    given[0] = 200;
    

    【讨论】:

      【解决方案4】:

      从以下行更改 whatIsGoingOn 方法

      given = new int[5];
      given[0] = 200;
      

      Arrays.fill(given,0);
      given[0] = 200;
      

      它仍然持有对原始数组的引用。不需要返回任何东西。

      【讨论】:

        【解决方案5】:

        Void 很简单,不会返回任何东西。将 void 替换为 int[] 以达到您的预期结果。也替换

        public void whatIsGoingOn(int[] given) {
           given = new int[5];
           given[0] = 200;
        }
        

        public int[] whatIsGoingOn(int[] given) {
           given = new int[5];
           given[0] = 200;
           return given;
        }
        

        最终结果应该是

        public int[] change(int[] given) {
           out.println(Arrays.toString(given)); //before-changes
           given = whatIsGoingOn(given); //make changes
           out.println(Arrays.toString(given));//after changes
           return given; //return the supposedly changed array
        }
        //Make changes:
        public int[] whatIsGoingOn(int[] given) {
           given = new int[5];
           given[0] = 200;
           return given;
        }
        

        【讨论】:

        • 嗯,谢谢你的信息。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 2014-10-14
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 2011-07-04
        • 2015-09-16
        相关资源
        最近更新 更多