Skip to content
CodeKruPro

Predict the output · Java

References, copies and mutability

Two names for one object, copies, and passing values to functions.

Learn: References, copies and pass by value in Java7 minute read

Many output questions hide one idea: two variables may point at the same object. If you can tell when that happens, you can predict the answer. Interviewers ask about it because the same idea causes real test bugs, such as test data that one test changes and another test then reads. The classic question "Is Java pass by value or pass by reference?" belongs here too.

Rule 1: a variable holds a value or a reference

A variable of a primitive type (int, double, boolean, char and the others) holds the value itself. A variable of any other type, including arrays, String and lists, holds a reference: a value that leads to an object somewhere else in memory (you can think of it as an address). Assignment copies what the variable holds. For an int that is the number. For a list it is the reference, so after b = a both names lead to the same list, and a change made through b shows through a.

Rule 2: Java always passes by value

A parameter is a variable in the method's definition. An argument is the value you give when you call the method. When you call a method, each parameter receives a copy of the argument's value. For a primitive, the method gets its own copy of the number and cannot change the caller's variable. For an object, the method gets a copy of the reference. That copy leads to the same object, so the method can change the object's contents. But pointing the parameter at a new object only changes the method's copy; the caller's variable still points at the original. This is why a swap method cannot swap the caller's variables.

import java.util.*;

public class Main {
    static void fill(List<String> list) {
        list.add("x");
        list = new ArrayList<>();
        list.add("y");
    }

    public static void main(String[] args) {
        List<String> items = new ArrayList<>();
        fill(items);
        System.out.println(items);
        List<String> same = items;
        List<String> copy = new ArrayList<>(items);
        same.add("z");
        System.out.println(items + " " + copy);
    }
}
[x]
[x, z] [x]
In main, items points at a list. Inside fill, the parameter first points at the same list and adds x, then is pointed at a new list holding y, which main never sees.
Changing the object is visible to the caller; reassigning the parameter is not.

Rule 3: immutable objects only look like values

An immutable object is one that cannot change after it is created (the opposite is mutable). String (see Strings and immutability), Integer and the other wrapper types (the object versions of int, double and the other primitives) are immutable. An operation such as s = s + "b", or n++ on an Integer, creates a new object and points the variable at it. Any other variable or parameter that referred to the old object still sees the old value. So a method can never change a caller's String or Integer; it has to return the new value.

Rule 4: copies are usually shallow

new ArrayList<>(list), array.clone() and Arrays.copyOf create a new container, but the elements are the same references as before. This is a shallow copy. For numbers and strings it does not matter. For a 2-D array (an array whose elements are arrays) or a list of mutable objects, a change made through the copy to an inner object shows in the original too. Replacing a whole slot in the copy does not.

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2};
        int[] b = a.clone();
        b[0] = 5;
        System.out.println(a[0] + " " + b[0]);
        String s = "a";
        String t = s;
        s = s + "b";
        System.out.println(s + " " + t);
    }
}
1 5
ab a

Rule 5: == checks identity, equals checks meaning

For references, == is true only when both sides point at the same object. equals means whatever the class defines. A class that does not override it (write its own version) inherits the version from Object (the class that every Java class builds on), which is the same as ==. Records (a short way to declare a data class), strings, wrappers and the standard collections override equals to compare contents.

Rule 6: final fixes the reference, not the object

A final variable cannot be pointed at another object, but the object it points at can still change. A final list can still have items added.

How to answer in an interview

For "pass by value or reference?", lead with the direct answer: "Java is always pass by value. For objects, the value that is copied is the reference." Then give the two-line proof: a method can add to a list it receives, but assigning a new list to the parameter does not change the caller's variable. For output questions, draw each variable as an arrow to its object and follow the arrows.

Common mistakes

  • Saying "objects are passed by reference". The reference is copied, which is pass by value.
  • Expecting b = a to copy a list or an array.
  • Expecting a method to change a caller's String.
  • Treating clone() of a 2-D array as a full copy.
  • Thinking final makes an object read-only.

Recap

Primitives hold values; everything else holds references. Assignment and method calls copy what the variable holds. Changing an object through any reference is visible everywhere; pointing one variable at a new object affects only that variable. Copies are shallow unless you copy the inner objects yourself.

9 questions0/9 solved

StatusQuestionDifficultyAsked in
Not startedTwo variables, one arrayEasy
Not startedPassing an int and an array to a methodEasy-MediumAsked in: Arista Networks
Pro+Changing a String inside a methodEasy-Medium
Pro+Mutating a parameter, then reassigning itMediumAsked in: Arista Networks
Pro+A swap method that does not swapMedium
Pro+Alias versus copy of an ArrayListMedium
Pro+Cloning a 2-D arrayMedium-HardAsked in: Capgemini
Pro+equals on a class and on a recordMedium-Hard
Pro+Incrementing a shared IntegerMedium-Hard
Not startedNot startedIn progressIn progressSolvedSolvedPro+Pro+

The first 2 questions of each topic are free. Pro+ opens every question.

Back to the plan