Arrays as Objects in Java
An array variable holds a reference to an array object and never holds the array itself; the array object lives in the heap.
Predicting a Change Through a Second Name
Suppose you create one array of numbers, then create a second variable and set it equal to the first. You then change one element through the second variable and ask what the first variable reports. Before reading on, decide your answer and be ready to say why. Many learners expect the first variable to be unaffected, because it feels as though each variable owns its own copy of the data.
What do you think happens?
After b[0] = 99 runs, what does a[0] print?
Reveal answer
99
Assigning a to b copies the reference, not the elements. Both a and b lead to the same array object, so the change made through b is visible through a.
The Labeled Box Picture and Where It Breaks
Many beginners picture an array variable as a labeled box that contains the array's elements, much like a jar contains beans. Under that picture, a variable named scores is simply the array of scores itself. This works well enough at first, but it gives wrong predictions once you start copying variables or passing arrays between methods.
The more accurate picture is that an array variable is a pointer to an array that lives somewhere else. The variable is a small name that tells Java where to find the real thing. The rest of the behavior in this article follows from that single correction.
A Variable Holds a Reference
An array variable holds a reference to an array object and never holds the array itself. The array object lives in the heap.
Every array in Java is an object, and objects are created in the heap. The variable and the array are therefore separate things connected by the reference. The variable refers, and the object holds the data.
The array type, such as int[] or String[], is itself a class, and arrays are created with a special form of the new operator. These syntax details matter less than the core relationship: the variable refers and the object holds the data.
Tracing Two Variables That Share One Array
Assigning one array variable to another copies the reference. It does not create a second array. The following example uses a list of temperatures that two parts of a program share.
30- temps is created with three elements
logCopy= temps copies the reference, so both names lead to the same object- The write through
logCopychanges the shared elements - Reading temps[0] shows the change
Predicting a Shared Temperature Update
A program creates temps and logCopy as described above, then runs logCopy[0] = 30. What is the value of temps[0], and why?
- 1Identify the references
temps and
logCopyeach hold a reference, and both references were copied from the same original assignment. - 2Find the object
Both references lead to one array object that holds 18, 21, and 19.
- 3Apply the write
logCopy[0] = 30 changes the element at index 0 of that single object. - 4Read through the other name
temps[0] reads the same object at index 0, so it now returns 30.
temps[0] is 30. The change was made through logCopy but is visible through temps because both names refer to the same array object.
Reassignment Leaves the Old Array Alone
Assigning a new array to an existing variable changes which object that variable refers to. The original array object is not modified by this assignment. Any other variable that still refers to the original object keeps seeing it unchanged.
1
7- x and y initially refer to the same array of 1 and 2
- x is reassigned to a new array object of 7 and 8
- y still refers to the original object, so y[0] is 1
- x now refers to the new object, so x[0] is 7
int[] x = {1, 2};
int[] y = x;x and y both refer to the array of 1 and 2
x = new int[]{7, 8};x refers to the new array of 7 and 8, while y still refers to the original array
When the Reference Is null
Because an array variable is only a reference, it can hold no reference at all. The source describes this as the value null, which means there is no actual array. A variable can be declared and still hold null, and the declaration does not guarantee that an array has been created and assigned to it.
Exception in thread "main" java.lang.NullPointerException- list is declared with type int[] and holds null
list.lengthtries to read from an array object- No array object exists, so the access throws
NullPointerException
Mistakes When Reasoning About Array Variables
Common mistake Believing that assigning one array variable to another copies the elements
What it looks likeint[] b = a; then b[0] = 99; and expecting a[0] to be unchangedWhy it failsAssignment copies the reference, so both names lead to one array object.
Do this insteadExpect changes made through either name to be visible through the other.
Common mistake Assuming a declared array variable always holds an array
What it looks likeint[] list = null; followed by list.lengthWhy it failsA declared variable can hold null, which means there is no array object behind it.
Do this insteadCheck for null before reading length or elements, or make sure an array is assigned first.
Common mistake Thinking reassignment changes the original array object
What it looks likeAfter x = new int[]{7, 8}, expecting y to show 7
Why it failsReassignment changes only which object x refers to. The original object is untouched.
Do this insteadTrack each variable's reference separately after every assignment.
Predict the Shared Array Result
Trace this code without running it. Predict the value printed by the last line, and explain which object each variable refers to at that point.
int[] p = {4, 5, 6};
int[] q = p;
q = new int[]{9, 9, 9};
q[1] = 0;
p[1] = 2;
System.out.println(q[1]);Hints
- Ask first whether q = new int[]{9, 9, 9} changes the object p refers to.
- After reassignment, q and p refer to different objects. Which write affects q's object?
Key Takeaways
- An array variable holds a reference to an array object and never holds the array itself; the array object lives in the heap.
- Assigning one array variable to another copies the reference, so both variables can change the same array.
- Reassigning a variable changes which object it refers to; the original array object is not modified and other variables still see it.
- An array variable may hold null, meaning there is no array object; accessing length or an element then causes a
NullPointerException, so check for null first.