By:
Category:

Java References for Newcomers

The term reference is unfortunately a bit overloaded. Some people hear the word and think of it in terms of, say, C or C++. The term was chosen, as I understand it, to distinguish from the term pointer. Java’s C legacy invariably led to a certain amount of confusion among those of us making the transition back in the early days of Java. References lack certain features, namely pointer arithmetic, and so the term is largely avoided in Java. It crops up but it’s not super common.

The most common questions crop up around passing references to a method and trying to reassign that reference in the method and see that change outside. For many this should work because they’re “passing in the object by reference.” After all, they can mutate the object by calling methods on it and see those changes after the method returns so why can’t they see the change when they reassign that parameter in the method?

This is because Java is pass by value. Everything passed to a method is copied on to the stack before the method is invoked. Let’s examine a simple piece of code:

Foo f = new Foo();
changeMe(f);

A common misconception of newcomers to the language is that f variable is an actual Foo instance. i.e., that f represents the actual object. What it is is a reference. This reference is, essentially, an address and a type. (Yes, it’s a bit more complicated than that. No it’s not really important just now.) The actual object lives on the heap and this reference just points to it. So what happens when we call that method changeMe()? This is where one of my favorite metaphors comes in.

Think of that f as a piece of paper. What’s on it you ask? In this case, we’ll say it’s a friend’s phone number. Whose number is it? For the moment, it’s Doug’s phone number. Now obviously that piece of paper isn’t actually Doug. It just tells us how to get a hold of Doug; how to reference him. To stretch the metaphor further, that slip of paper now has the type of “friend’s phone number.”

We’re at a party and someone needs Doug’s phone number. When we give that number to someone we have a problem. That person needs the phone number but don’t I need it, too? What we do? We make a copy of it! We get another piece of paper to store a “friend’s phone number” on it and copy down Doug’s phone number. Then we can happily hand it off to that person. Now that other person can do whatever they want with their piece of paper but nothing they do can change my piece of paper. They can even change it to have Bob’s phone number on it but that doesn’t change the fact that my paper still has Doug’s number; it still points to Doug.

That other person can call Doug and feed him all kinds of bad information. Doug might not be so happy next time I call him. That person used their copy of the phone number to call Doug and tell him lies about me. But they did it with a copy of the phone number I gave them and not with my piece of paper with his phone number on it.

This is what’s happening when we pass references in to methods. The values get copied on to the stack in a new reference. The method can do all sorts of things with that reference but doesn’t affect the original reference in any way. We can have as many references to a single object as we need but we’d still only ever have that one object in memory. At least, until we make another friend.