user4425952
user4425952

Reputation:

Inexplicable Array assignment behavior in Java

So here it goes. I've been building a piece of software for a bigger project, and right now, I am simply baffled by the way Java treats my code. I have absolutely no idea as to why Java behaves the way it does right here.

It seems to skip part of my code, and assigns values to a different array than I expected when no according method is called.

I have walked over this for a few hours now with the IntelliJ Debugger, inspecting everything ever so closely, but I have not found a single reason as to why things happen the way they do.

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.
    }
}

After calling putNumber the first time, using putNumber again simultaneously puts the value in both variables (oldNumber and Number) instead of only in number[0].

I continued to simplify my code as far as possible so this example is more hands-on. Obviously, the real example where I found this had arrays longer than a single element.

I also tested it with multidimensional arrays, as well as object arrays. No change in the behavior.

I am completely puzzled now and have absolutely no idea how to go on. If you can shed any light on this topic, please do so. I am more than confused.

Upvotes: 0

Views: 100

Answers (4)

Florian Schöffl
Florian Schöffl

Reputation: 499

In the putOld function you assigned the reference of the first array to the other. After the first call oldNumber is a pointer to number and if you change a value in one, the other one is affected too.

If you want to copy the values System.arraycopy().

Upvotes: 2

Thilo
Thilo

Reputation: 262474

When you assign

oldNumber = number

you don't make a copy of the values in the array. oldNumber will point to the exact same array (and future changes in either variable reflect in the other).

You can make a copy with

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

Upvotes: 2

rgettman
rgettman

Reputation: 178243

This line isn't doing what you think it's doing.

oldNumber = number;

It isn't copying the contents of one array to another. It is making the reference variable oldNumber refer to the same array object as number refers to.

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

So, any change through either variable writes through to the same array, and the change is visible through both references, which refer to the same array.

Then later you call Arrays.equals with references to the same array, so they are "equal".

You want to copy the number with this line instead:

oldNumber[0] = number[0];

Upvotes: 3

Greg Hewgill
Greg Hewgill

Reputation: 992747

The following assignment statement:

    oldNumber = number;

makes oldNumber and number point to the same underlying array. Perhaps what you want is to make a copy:

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

See the documentation for System.arraycopy for full details.

Upvotes: 6

Related Questions