Skip to content
Theory · Arrays · lesson 5 of 8

An array is a reference

The assignment int b = a puts a copy of the number into b, and from then on each variable lives on its own. Let's do the same with an array and see what happens:

JAVA
public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] b = a;
        b[0] = 9;
        System.out.println(b[0]); // 9
        System.out.println(a[0]); // 9
    }
}

Let's go line by line:

  1. int[] a = {1, 2, 3}; creates an array of three elements.
  2. int[] b = a; declares the variable b and puts the value of a into it.
  3. b[0] = 9; changes the first element through b.
  4. System.out.println(b[0]) prints 9, as expected.
  5. System.out.println(a[0]) prints 9 too, even though we wrote nothing to a.

To see where the nine came from, let's go back to the row of lockers. The row itself stands in the changing room. The variable a holds not the row but a ticket with its address: the ticket leads you to the right row.

The line int[] b = a made a copy of the ticket. Now there are two tickets but still one row. So whatever is put into a locker using ticket b, the holder of ticket a sees too.

The variable holds a reference

When the program runs {1, 2, 3} or new int[3], the JVM creates the array itself in a separate area of memory, the heap. The variable a gets not the array but a reference: a value by which the JVM finds the array on the heap. That is the ticket. Everything the JVM creates on the heap is called an object, which is why the widget below labels the arrays "object 1" and "object 2".

The rule for = has not changed: assignment copies the value of a variable. The difference is that the value of an int[] is a reference, so int[] b = a copies the reference, not the elements. Now a and b lead to one array.

Types whose variables hold references are called reference types. The array is the first such type we look at closely. The eight primitive types have no references: an int variable holds the number itself. So an element of an int[] is an ordinary int, and int x = a[1]; copies the number: writing x = 7 does not touch the array.

In the widget the first three lines are the same as in the program above, and the fourth creates an array c with the same numbers that a now holds. Run the lines one at a time and watch which object each variable leads to. After the last line the widget offers three comparisons: before you press one, try to guess the answer.

LiveTwo references to one arrayvariables: 0 · objects: 0
object numbers are illustrative

The program has not started yet. Press the button to run the first line.

Watch which object each variable leads to

Here the ticket picture is off. A real ticket exists as a single copy and cannot be duplicated, while Java copies a reference as many times as you like. And you never see the address on the ticket: Java does not show a program where on the heap an array lives.

An array as a method parameter

A reference is copied when you call a method too. A parameter gets a copy of the argument's value, and the value of an array is a reference. So the method and the caller hold tickets to the same row. Say the method's parameter is called nums:

  • nums[0] = 0; changes an element of that very array, and the caller will see that zero;
  • nums = new int[3]; rewrites only the method's copy of the ticket, and the caller's variable still leads to the old array.

In an interview this is put as: Java always passes arguments by value, and for an array the value is a reference.

How to compare two arrays

The whole program from the widget prints three comparisons:

JAVA
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] b = a;
        b[0] = 9;
        int[] c = {9, 2, 3};
        System.out.println(a == b);              // true
        System.out.println(a == c);              // false
        System.out.println(Arrays.equals(a, c)); // true
    }
}

== compares references

The == operator compares the values of two variables. For int those are numbers, and for arrays they are references. So for arrays == answers the question "is this the same array?":

  • a == b gives true: b holds a copy of the same ticket;
  • a == c gives false: c has its own array, even though its elements are the same.

Arrays.equals compares elements

Arrays.equals(a, c) compares the lengths of the arrays and their elements in order. Here the lengths are equal and the elements 9, 2, 3 match, so the result is true. Order matters: {1, 2} and {2, 1} are different arrays to it.

Interviewers like to ask this: how is == different from comparing contents? For arrays the answer is: == compares references, and Arrays.equals compares the length and the elements.

A real copy

When you need a second, independent array with the same elements, you create it with the method Arrays.copyOf:

JAVA
int[] src = {1, 2, 3};
int[] copy = Arrays.copyOf(src, src.length);
copy[0] = 9;
System.out.println(Arrays.toString(src));    // [1, 2, 3]
System.out.println(Arrays.toString(copy));   // [9, 2, 3]
int[] longer = Arrays.copyOf(src, 5);
System.out.println(Arrays.toString(longer)); // [1, 2, 3, 0, 0]

Arrays.copyOf sets up a new row of lockers and copies the elements into it. The second argument is the length of the new array:

  1. With the length src.length you get an exact copy. Writing to copy does not touch src.
  2. With a length greater than the original, the extra cells are filled with zeros: this is how an array is "made longer".
  3. With a length less than the original, the copy is cut short: Arrays.copyOf(src, 2) gives [1, 2].

Common mistake

You wanted a sorted copy and to keep the original order:

JAVA
int[] scores = {30, 10, 20};
int[] sorted = scores; // ✗
Arrays.sort(sorted);
System.out.println(Arrays.toString(scores)); // [10, 20, 30]

The line sorted = scores copied only the reference, and Arrays.sort sorted the one and only array. The original order 30, 10, 20 is lost. You need a real copy: int[] sorted = Arrays.copyOf(scores, scores.length);.

Key points

  • An array variable holds a reference to the array on the heap, not the elements themselves.
  • int[] b = a copies the reference: a and b lead to one array, and a write through b shows through a.
  • == compares references, and Arrays.equals compares the length and the elements in order.
  • An independent copy is created by Arrays.copyOf(a, a.length).