Java中令人费解的数组赋值行为

时间:2015-01-07 00:57:16

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

所以这就是它。我为一个更大的项目构建了一个软件,而现在,我对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]

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

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

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

4 个答案:

答案 0 :(得分:6)

以下转让声明:

    oldNumber = number;

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

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

有关详细信息,请参阅documentation for System.arraycopy

答案 1 :(得分:3)

这条线并没有按照你的想法行事。

oldNumber = number;

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

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

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

然后你用同一个数组的引用来调用Arrays.equals,所以它们是#34;相等"。

您希望使用此行复制数字:

oldNumber[0] = number[0];

答案 2 :(得分:2)

分配时

oldNumber = number

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

您可以使用

制作副本
oldNumber = Arrays.copyOf(number, number.length);

答案 3 :(得分:2)

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

如果要复制值 System.arraycopy()