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
moggyof typeCatand theJVMallocates space for it. - Creation - Tells the
JVMto allocate space on The Heap for a newCatobject. - Assignment - Assign the new
Catobject 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:
TestCat2 class.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:
Testinstanceof class.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.