Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Fundamentals › Java

References

What does it mean to store an object in a variable?

In Card a = new Card();, what is inside variable a is not the Card object itself but a value that refers to that object. This value is called a reference. So when you store a variable in another variable, as in Card b = a;, the object is not copied. Only the reference is copied, and a and b come to refer to the same object. If you change the contents of the object through one of them, it is changed when you look through the other too. A variable of a primitive type such as int is different. The value itself is inside it, so int b = a; copies the value. In this lab you run the same lines while changing what is stored in b: a reference copied from a, an object newly created with new, an object newly created and then given only the owner copied over, and an int value. You can see what happens to a after b is changed, and how many Card objects were created.

Checked against real execution · Four combinations were compiled with javax.tools on JDK 21, run, and checked against the results

Concepts in this lab

Reference
A reference is a value that refers to an object. When you create an object with new, a reference to that object is produced, and a variable of a class or interface type holds not the object itself but this reference (or null, which means that it refers to no object). There can be several references to the same object, so when you assign as in Card b = a;, the object is not copied. Only the reference is copied, and a and b refer to the same object. If you then change the state of the object through one variable, it is changed when you read it through the other variable too. When you compare two references with ==, it asks not about the contents of the object but whether both are null or both refer to the same object.
Classes and objects
A class is a blueprint that states which fields (data) and methods (behavior) something has, and an object is the actual thing that is created in memory (on the heap) by using new with that blueprint. An object is also called an instance. You can create many objects from one class, and each object has its own field values. A variable holds not the object itself but a reference to where the object is.
Primitive types and reference types
These are the two kinds into which the types of Java are divided. There are eight primitive types, byte, short, int, long, float, double, char, and boolean, and a variable of one of them holds the value itself. Reference types are all the other types, such as classes, interfaces, and arrays, and a variable of one of them holds a reference to an object, not the object itself. So assigning a variable of a primitive type copies the value, and the two variables do not affect each other, but assigning a variable of a reference type copies the reference, and the two variables come to refer to the same object. A variable of a reference type can hold null, which means that it refers to no object, and a variable of a primitive type cannot hold null.
Identity and equality
Identity means that two references point to the same object in memory, and you compare it with the == operator. Equality means that two objects logically have the same value, and you compare it with the equals() method. If you use == to compare strings or value objects, the result can be false even when the contents are the same.

Try these

Running with the default settings

  1. The line Card a = new Card(); runs. new Card() creates one Card object (object A in the diagram), and a value that refers to that object is stored in variable a. This value is called a reference. The object is not inside a. a refers to object A.
  2. The line a.owner = "Alice"; runs. It goes to the object A that a refers to and stores Alice in the owner of that object.
  3. The line Card b = a; runs. What is inside a is "a reference to object A," and this reference is copied to b. Object A is not copied. No new object was created, and there is still 1 object. a and b refer to the same object A.
  4. The line b.owner = "Bob"; runs. It goes to the object that b refers to and stores Bob in its owner. The object that b refers to is object A, and the object that a refers to is also object A. So the owner of object A changes from Alice to Bob.
  5. The line System.out.println(a.owner); runs. It reads the owner of the object A that a refers to and prints Bob. Nothing was changed through a, yet it has changed, because the object changed through b is the very object that a refers to.
  6. The line System.out.println(a == b); runs. When you use == on two variables, it compares whether the values inside them refer to the same object. a and b both refer to object A, so it prints true. It does not compare the text in owner.
  7. main ends. In this run, new Card() ran 1 time and 1 Card object was created. A line that stores a value in a variable did not increase the number of objects. In this code, objects were created only by new Card().

Result of this run

Code

class Card {
    String owner;
}

public class Main {
    public static void main(String[] args) {
        Card a = new Card();
        a.owner = "Alice";
        // b holds the very object that a refers to. No new object is created
        Card b = a;
        b.owner = "Bob";
        System.out.println(a.owner);
        System.out.println(a == b);
    }
}

Assumptions of this model

The runtime environment is JDK 21.0.12.1 (javac 21). All four combinations were compiled with javax.tools from the same source as the code on the screen, loaded with a new class loader, and Main.main was run, and the results were checked against the captured standard output. In the source of the Probe (the checking program), only lines that count Card objects (an increment of a static variable and in the constructor, and a few output lines) were added, and for every combination it was confirmed that, with those lines removed, the text is identical to the code on the screen line by line. What was checked is the two output lines, the number of Card objects created, and the facts that the step sentences rely on. The facts are the number of objects right after the line Card b = ...; ran (for the combination that stores new Card(), right after the owner was copied over), the value of a == b, the values of the owner of the objects that the two variables refer to, and whether those two values are the same. The documentation was checked by opening the Java Language Specification (Java SE 21) directly. That there are reference values that refer to objects, that when two variables refer to the same object a state changed through one variable can be read through the other, and that an int value is copied on assignment so that the two are separate follow sections 4.2 and 4.3.1 (example 4.3.1-2); that a variable of a primitive type holds a value of that primitive type, and a variable of a class type holds null or a reference to an object of that class, follows sections 4.12.1 and 4.12.2; and that == on references is true when both are null or refer to the same object follows section 15.21.3. That == on int variables compares values (section 15.21.1) was not confirmed by opening the documentation, and was confirmed only by the result of this run. The screen draws the texts of owner, Alice and Bob, as if they were values inside the object, but owner is also a reference that refers to a String object. This lab does not cover that difference, and it does not cover how string constants come to refer to the same object. equals, which asks whether the contents of objects are the same, is covered in "In-depth lab: == and equals". Where variables and objects are placed in memory is not something this lab covers or checked. What this lab showed is the behavior that the value stored in a variable refers to an object, and that assigning copies that value.

Previous lab: Classes and objects · Next lab: null

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these