【问题标题】:Inexplicable Array assignment behavior in JavaJava中莫名其妙的数组赋值行为
【发布时间】:2015-03-04 18:44:03
【问题描述】:

就这样吧。我一直在为一个更大的项目构建一个软件,而现在,我只是对 Java 处理我的代码的方式感到困惑。我完全不知道为什么 Java 的行为方式是这样的。

它似乎跳过了我的部分代码,并在没有调用相应方法时将值分配给与我预期不同的数组。

我已经用 IntelliJ 调试器检查了几个小时,仔细检查了所有内容,但我没有找到一个原因来解释为什么事情会以这种方式发生。

package com.whatareyoudoing.java;
import java.util.Arrays;

/**
 * WHAT THE ACTUAL DUCK
 */
public class WTF {
    private int[] number;
    private int[] oldNumber;

    public WTF() {
        number = new int[1];
        oldNumber = new int[1];
    }

    public void putNumber(int c) {
        number[0] = c;
    }

    public void putOld() {
        if(Arrays.equals(oldNumber, number)) {
            System.out.println("Nothing to do!");
            return; //How on earth can they literally be the same?!
        }
        oldNumber = number;
    }

    public void doWTF() {
        putNumber(1); 
        putOld(); // Works.
        putNumber(2); // Expected Result: number = 2; oldNumber = 1 [NOPE] number = 2; oldNumber = 2
        putOld(); // [NOPE] Simply Skips with "Nothing to do"
        putNumber(3); // Same odd behaviour
        putOld(); // Aaaand skips again.
    }
}

第一次调用 putNumber 后,再次使用 putNumber同时将值放入两个变量(oldNumberNumber)中,而不是仅放入 number[0]强>。

我继续尽可能简化我的代码,因此这个示例更加实用。显然,我发现它的真实示例中的数组比单个元素长。

我还使用多维数组以及对象数组对其进行了测试。行为没有变化。

我现在完全困惑,完全不知道如何继续。如果你能对这个话题有所了解,请这样做。我很困惑。

【问题讨论】:

    标签: java arrays intellij-idea variable-assignment skip


    【解决方案1】:

    在 putOld 函数中,您将第一个数组的 reference 分配给另一个数组。在第一次调用之后 oldNumber 是一个指向数字的指针,如果你改变一个值,另一个也会受到影响。

    如果要复制值System.arraycopy()

    【讨论】:

      【解决方案2】:

      当你分配时

      oldNumber = number
      

      您不会复制数组中的值。 oldNumber 将指向完全相同的数组(两个变量的未来变化会反映在另一个变量中)。

      你可以复制

      oldNumber = Arrays.copyOf(number, number.length);
      

      【讨论】:

        【解决方案3】:

        这条线没有做你认为它正在做的事情。

        oldNumber = number;
        

        它不是将一个数组的内容复制到另一个数组。它使引用变量oldNumber 引用与number 所引用的相同的数组对象。

        oldNumber ----> [1]
        number    -------^
        

        因此,通过任一变量进行的任何更改都会写入同一个数组,并且通过引用同一数组的两个引用可以看到更改。

        然后你调用 Arrays.equals 引用同一个数组,所以它们是“相等的”。

        你想用这一行复制数字:

        oldNumber[0] = number[0];
        

        【讨论】:

          【解决方案4】:

          下面的赋值语句:

              oldNumber = number;
          

          使oldNumbernumber 指向同一个底层数组。也许你想要的是复制一份:

              System.arraycopy(number, 0, oldNumber, 0, number.length);
          

          详情请参阅documentation for System.arraycopy

          【讨论】:

          • 那么将数组的值分配给另一个数组的正确方法是什么?感谢您的快速答复!
          猜你喜欢
          • 2012-11-14
          • 1970-01-01
          • 2012-05-19
          • 1970-01-01
          • 1970-01-01
          • 2018-12-23
          • 2012-03-12
          • 2019-02-04
          • 1970-01-01
          相关资源
          最近更新 更多