Next page | Contents page |

Values, references and null

When we assign something to a variable having a primitive type, we are assigning a value.

	int x = 1234;

Pretty obviously the memory location set aside for x by the JVM will contain the value 1234 after that statement.

But what happens in the case of class types?

	Customer c = new Customer ("John", "Smith", "ABC123");

Objects are constructed in a large area of memory reserved by the JVM which is called the "heap". The JVM knows where it has put each object in the heap but it will not tell us. This is to avoid the kinds of difficulties that C++ and other programmers got into in the past because they were allowed to do arithmetic on the addresses of objects and poke around in them however they liked. (People coming from C++ to Java, as I did myself, may well find this very frustrating at first. Believe me, it is for your own good and eventually you will come to realise the benefits.)

The JVM makes up a ticket number by which to refer to each object. In Java these ticket numbers are called references. C/C++ programmers might tell you they are just pointers by a different name. Maybe they are, but that is irrelevant.

In the example above where we have created a Customer object, what we have assigned to the variable c is in fact the JVM's reference to the object, so that when we use c the JVM knows where to find the corresponding object.

It is really important to remember this: base type variables hold values but class type variables hold references (to objects). (And later on, interface and enum type variables also hold references.) The reason why this is important can be seen by considering the next example:

	Person p = new Person ("Fred");
	Person q = p;   // Still only 1 object... p & q both refer to it now

Contrast with base type assignment! Assignments and copying of objects or complete arrays have to be considered carefully in terms of references.

Methods

Arguments to methods use the same rule: pass the value for base types, pass the reference for objects & arrays. Inside a method a copy of the passed value/reference is worked on so it doesn't affect the original. But using the reference to work on a part of an object or array does affect the original.

	void changeInt (int x)
	{
		while (x > 0) System.out.println (x--); 
	}

doesn't affect the original x, only a local copy.

	void changePoint (Point p)
	{
		while (p.x > 0) System.out.println (p.x--); 
	}

does affect the x field of the original object.

Obvious? A reason to make p.x private?

null

null is a special value for a class variable that does not currently hold a reference to an object. When a class type field is declared but not initialised it is in fact given the null reference:

	private Customer c;

You can also explicitly assign the null reference and test for it:

	customer1 = null; // Will enable garbage collection if there is no other reference to the object
	
	if (null == customer2)
	{
		// ... whatever
	}

Some methods in the API say they will return null in certain circumstances, so you need to test for that after calling any of them.

Objects and local scope

An object may be constructed with a local reference which goes out of scope but as long as there are still references to the object it will not be destroyed. Eg,

	public MyClass someProcess (int a)
	{
		int b = myMethod (a);         // Local int
		MyClass mo = new MyClass (b); // Local reference
		return mo;     // Caller gets copy of reference
	}

After this, b and mo go out of scope and are tidied up but the returned reference (if the caller assigns it to something) ensures the object survives.

Next page | Contents page |