Reference VariablesS2C Home « Reference Variables
Java comes with two types of variables to choose from, primitives and reference. In this lesson we look at reference variables and how to use them in Java. We discussed primitive variables in the Fundamentals section in the Primitive Variables lesson.
Reference variables are concerned with objects and how we access them. The reference variable doesn't hold the object itself but some bits that act as a pointer to an address in memory where the object exists. How the
JVM
holds these bits isn't important for us as developers, just the fact that this memory address pointer is used by the JVM
to access a unique object. There are three steps involved in object creation:
So lets go through the three step process above:
- Declaration - Here. we declare a reference variable named
moggy
of typeCat
and theJVM
allocates space for it. - Creation - Tells the
JVM
to allocate space on The Heap for a newCat
object. - Assignment - Assign the new
Cat
object to the reference variablemoggy
.
The new
Operator Top
As you can see from the diagram above object creation is a three step process involving declaration, creation and assignment. We create objects using the new
operator which allocates space
on the heap for an existing reference variable or one declared at instantiation:
package com.server2client;
/*
Examples of class instantiation
*/
public class Testinstanceof {
public static void main (String[] args) {
Cat moggy = new Cat(); // Declare, create and assign Cat instance
Cat moggy2; // Declare Cat reference
moggy2 = new Cat(); // Allocate and assign Cat instance
}
}
The Heap
Top
The Heap
is the area of memory that the JVM
allocates to store our objects in. As long as we have a reference to an object then it exists on the Heap
. Of course computer memory is finite and so the
JVM
needs to discard objects on the Heap
and call the finalize()
method of the Object
class, when their scope ends and there are no live references to them, or they become unreachable: this is known as garbage collection (GC). Setting a reference to null
will also deprogram
it from any object; in fact trying to access a null pointer will cause a NullPointerException
runtime error. To clarify this lets go through the creation of some objects and see what happens to them on the
Heap
and when they become eligible for GC. The following slide show depicts a scenario, just press the buttons to step backwards and forwards.
Lets look at some code to illustrate the above scenario:
package com.server2client;
/*
Test Class2 for Cat
*/
public class TestCat2 {
public static void main (String[] args) {
Cat moggy = new Cat(); // Create a Cat instance
Cat tigger = new Cat(); // Create a Cat instance
Cat tabby = new Cat(); // Create a Cat instance
tabby = tigger;
tigger = moggy;
moggy = null;
tigger = null;
tabby.talk(); // execute the talk() method
tigger.talk(); // execute the talk() method (runtime error)
}
}
Running the TestCat2
class produces the following output:
The assignments of the reference variables happen as in the slide show. tabby
can talk as his reference variable still points to a Cat
object on the heap. When we try and get tigger
to talk
we get a NullPointerException
runtime error as this reference is now null.
The Stack
Revisited Top
In the Fundamentals section in the Method Scope lesson we took our first look at the Stack
and used primitive local
variables for our examples. What we haven't mentioned so far is reference variables and the Stack
. The rules for local
variables that are reference variables are the same as local
variables that are primitives. The following slide show shows this in action, just press the buttons to step backwards and forwards.
So to summarize, a local
variable, whether primitive or reference, is alive as long as its method exists on the Stack
. You can only use a methods local
variables while the method is at the top of the stack (is executing).
The instanceof
Operator Top
We looked at operators in great detail in the Operators and Bitwise Operators lessons of the
Fundamentals section of the site. There was an admission from the list, the instanceof
operator, which we will discuss now as this operator can only be
used with reference variables. We use the instanceof
operator to find out whether an object is of a particular type. Because Java is a strongly typed language, it cares about the type of the
variables we declare and try to use. So just be aware when using the instanceof
operator to check for a String
object, when you have an instance of Monkey
that
knows nothing about String
, you will get a compiler error.
package com.server2client;
/*
Test Class for instanceof Operator
*/
public class Testinstanceof {
public static void main (String[] args) {
Cat moggy = new Cat();
if (moggy instanceof Cat) {; // Check for Cat instance
System.out.println("moggy is a Cat.");
}
}
}
Running the Testinstanceof
class produces the following output:
The screenshot shows the output from the Testinstanceof
test class, showing that moggy
is indeed a Cat
.
We can also use the instanceof
operator with polymorphic types and this is discussed in Using instanceof
With Interfaces.
Related Quiz
Objects & Classes Quiz 4 - Reference Variables
Lesson 4 Complete
In this lesson we looked at reference variables.
What's Next?
We have used methods throughout the lessons so far so its time for a thorough investigation of what we can do with these members.