Reference VariablesHomepage  « Learn Java5 « 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 Beginning Java5 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 this bits isn't important for us as programmers, 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:

object creation

So lets go through the three step process above:

  1. Declaration - Here. we declare a reference variable named moggy of type Cat and the JVM allocates space for it.
  2. Creation - Tells the JVM to allocate space on The Heap for a new Cat object.
  3. Assignment - Assign the new Cat object to the reference variable moggy.

The new Operatorgo to top of page 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:


/*
  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 Heapgo to top of page 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 button to step through it.

heap 1 heap 2 heap 3 heap 4 heap 5

In this slide we create 3 Cat objects and these are placed on the Heap and can be accessed through their reference variables.

In this slide we assign the reference variable tabby to reference variable tigger. This means that the Cat object that was previously referenced by tabby is now unreachable and as such is eligible for GC. tigger and tabby now refer to the same Cat object.

In this slide we assign the reference variable tigger to reference variable moggy and so moggy and tigger now refer to the same Cat object. This also means that the Cat object that was previously referenced by tigger is now only referenced by tabby.

In this slide we assign null to the reference variable moggy and so the pointer in this reference variable refers to nothing. tigger still refers to the Cat object that moggy previously did.

In this final slide we assign null to the reference variable tigger and so the pointer in this reference variable refers to nothing. This means that the Cat object that was previously referenced by tigger is now unreachable and as such is eligible for GC.

Press the button below to cycle through our Heap explanation.


Lets look at some code to illustrate the above scenario:


/*
  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)
    }
}

Save, compile and run the file in directory   c:\_ObjectsAndClasses in the usual way.

run heap

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 Revisitedgo to top of page Top

In the Beginning Java5 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 button to step through it.

stack 1 ref stack 2 ref stack 3 ref stack 4 ref stack 5 ref

Press the buttons below to cycle through our stack explanation.


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 Operatorgo to top of page Top

We looked at operators in great detail in the Operators and Bitwise Operators lessons of the Beginning Java5 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.


/*
  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.");
        } 
    } 
}

Save, compile and run the Testinstanceof test class in directory   c:\_ObjectsAndClasses in the usual way.

run runinstanceof

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.

Reference Variables Quizgo to top of page Top

Try the quiz below to test your knowledge of this lesson

Question 1 : Where are objects stored?
- Objects are stored on the heap.
Question 2 : Where are reference variables stored?
- Reference variables are stored on the stack.
Question 3 : How does the JVM reclaim memory?
- The JVM reclaims memory through garbage collection.
Question 4 : Two ways an object becomes eligible for garbage collection are when it goes out of scope and no live references exist and when all pointers to it are set to null. What is the third?
- An object becomes eligible for garbage collection when the object is unreachable.
Question 5 : How can we check the reference type of an object?
- We can check the reference type using the <code>instanceof</code> operator.
Question 6 : What is output from the following code snippet?

public class Testinstanceof {
public static void main (String[] args) {
String moggy = new String();
Cat string = new Cat();
if (string instanceof String) {; // Check for Cat instance
System.out.println("string is a String.");
}
}
}
- You will get a compiler error for <em>inconvertible types</em>.
Question 7 : A reference variable holds an objects state?
- false - A reference variable holds a pointer to an object on the heap.
Status Bar Please select an answer

What's Next?

In the next lesson we look at instance variables, how to use them and their scope.

<<  Class Structure & Syntax                    Methods  >>

go to home page Java5 Tutor Homepage go to top of page Top