1.2. Reference Type Examples¶
In Java, the reference types (§4.3) are class types, interface types, and array types. Of these three, you are likely familiar with declaring variables of both class and array types. Below are two example declarations of reference type variables:
Person ada; // A class type variable (valid only if we have a class called Person on the classpath)
double[] array; // An array type variable
An object is really just a collection of variables that are defined
by a class. It is not uncommon to describe Java objects as dynamically
constructed instances of a class. When an object is constructed, its
collection of variables is stored contiguously in some location in
memory, which we usually call the object’s reference. This is
important because, in Java, the possible values of a reference type are
references to compatible objects (or null
).
Note
A reference variable either stores:
null
The location of an object in memory (a valid reference)
Below we describe various scenarios in which you may encounter/use reference variables in your code.
Example 1: Refer to No Object
Consider the following declaration and initialization:
Scanner s = null;
The variable s
has Scanner
as its type and null
as its
value. In Java, null
is a reference that can always be assigned
to any reference type, and it is used to denote that no object is
being referred to. Therefore, we might say that variable s
does
not currently refer to any object.
Under the Hood: Remember, s
is an alias for some location
in the computer’s primary memory (RAM). Since we don’t know exactly
where s
will be located when the program runs, we will use an
arbitrary number to denote this location. Here, we will use the
value 800
(we could have chosen any arbitrary value). The
mapping of s
to a memory location all happens under the hood
and requires no explicit actions by the programmer. The way this
looks internally can be seen below. In the diagram, we use 800
instead of s
since that’s what really happens in the
computer. Since we assigned null
to s
, the value at
location 800
is null
.
800: [ null ]
Since using the variable name is more readable and does not require us to choose an arbitrary address, it is more common to diagram this using the variable name:
+------+
s | null |
+------+
Example 2: Refer to Some Object
Now consider the following declaration/initialization:
1Scanner s;
2s = new Scanner(System.in);
Despite its length, there is a lot happening in that code:
the variable
s
is declared withScanner
as its type (line 1);a
Scanner
object is constructed (starting withnew
on line 2); andthe object’s reference is assigned to
s
(using=
on line 2).Since the value of
s
is now a reference to someScanner
object, we might say thats
refers to someScanner
object.
Under the Hood: Let 800
again denote the memory location that
stores s
‘s value and 12048
denote the memory location of the
constructed Scanner
object. Again, these values are arbitrary. The
diagram below demonstrates the values that are stored at these two
memory locations. Pay close attention to fact that 800
(or s
)
does not store the Scanner
object’s contents. Instead, s
is the
address where the Scanner
object resides in memory. Understanding
this idea is the key to understanding how reference variables work in
Java.
800: [ 12048 ]
...
12048: [ scanner object contents ... ]
It is more common to diagram this using the variable name and an arrow
to the object (since we may not know or care what the actual value of
the memory address of s
):
+--+ +----------------+
s | -|----◆| |
+--+ | |
+----------------+
Important: When a method is called using s
(for example,
s.nextLine()
), the object that s
refers to is known as the
calling object. Non-static methods called using s
are said to
operate on the calling object. Since the reference in the value of s
can change over time, the calling object can also change.
Test Yourself (Example 3)
Consider the following initializations:
1Scanner s = new Scanner(System.in);
2Scanner t = s;
Before moving on, take a moment to draw a diagram on a sheet of paper that shows how this looks under the hood (sometimes called a memory map or a memory diagram). Try drawing both versions of the diagram. You can come up with any arbitrary memory addresses that you wish. This example is a bit tricky but critical to understanding reference variables.
Do the best you can before looking at the solution!
Test Yourself Solution (Don’t open until completing the question above)
Your drawing should look very similar to the previous example with an
extra variable for t
that contains the same value as the variable
s
. We provide the more common version of this diagram below.
The first line is the same as in Example 2. On the second line: i) the
variable t
is declared with Scanner
as its type; ii) the value
of s
is retrieved by the computer; then iii) the value is assigned
to t
. Since the value of t
is now the same as the value of
s
, we might say that s
and t
both refer to the same
Scanner
object.
In our solution, we changed the memory addresses to other values, but any numbers are allowed. Here are the values we chose:
Object / Variable |
Address |
---|---|
|
|
|
|
|
|
Diagram 1:
21: [ 78421 ]
481: [ 78421 ]
...
78421: [ scanner object contents ... ]
Diagram 2:
+--+ +----------------+
s | -|----◆| |
+--+ | |
+----------------+
◆
+--+ |
t | -|--------+
+--+
This is an interesting scenario because the calling object for s
and
the calling object for t
now refer to the same object!
Rapid Fire Review
What is stored in a reference variable in Java?
The actual object.
The memory address where the object is stored.
The class type of the object.
The size of the object in memory.
In the following declaration, what does the variable s store?
Scanner s = null;
A reference to an object of type
Scanner
.The value
null
, indicating thats
does not refer to any object.The specific memory location
800
.The
Scanner
class.
Given the following code, what happens when the second line executes?
Scanner s; s = new Scanner(System.in);
A new
Scanner
object is created, and its reference is assigned tos
.The value
null
is assigned tos
.The
Scanner
object is destroyed.The value of
s
is set to an arbitrary memory address.
In the memory diagram below, what does the line from
s
to theScanner
object represent?+--+ +----------------+ s | -|----◆| | +--+ | | +----------------+
The actual
Scanner
object.The method that
s
calls.The reference stored in
s
that points to theScanner
object.The size of the
Scanner
object in memory.