Java 7 for Absolute Beginners

(nextflipdebug5) #1

CHAPTER 6 ■ OBJECT-ORIENTED PROGRAMMING


When you pass a primitive to a method, the JVM preserves the original value and makes a new
primitive (literally, a copy) with the same value for use in the method. The JVM consequently has two
values, the original primitiveInt field in PassByTest and the primitiveInt argument to the passBy
method. Therein lies the heart of the issue: Because the JVM makes a new primitive, the original never
gets modified.
Even if the passBy method returned the primitive value, it would not change the original value. Until
we re-assign the original value, it remains whatever it was originally set to (0 in this case). If we assign the
return value of the method to the original primitive, that works. Again, though, we have two different
values, and we assign the value of the new one (created by the method) to the old one. Consider the
modified PassByTest class in Listing 6-17.

Listing 6-17. PassByTest with a return value for the passBy method

package com.apress.java7forabsolutebeginners .examples.hello;

public class Hello {

static int primitiveInt = 0;
static IntegerWrapper intWrapper = new IntegerWrapper();

public static void main(String[] args) throws Exception {
passBy(primitiveInt, intWrapper);
System.out.println("primitiveInt = " + primitiveInt +
"; intWrapper.objectInt = " + intWrapper.objectInt);
}
public static int passBy(int primitiveInt, IntegerWrapper intWrapper) {
primitiveInt++;
intWrapper.objectInt++;
return primitiveInt;
}
}

The passBy method now returns an int, but the output remains the same (primitiveInt remains 0).
I know I've hammered the point repeatedly, but, again, primitiveInt in the method is a different
primitive than the primitiveInt field in the class. Remember, the compiler makes a copy of it when it
calls the method.
Now, let's look at what happens to IntegerWrapper.objectInt. Because IntegerWrapper is an object,
the value that gets passed is its address in memory (that is, a pointer to the object). There's only one
IntegerWrapper object, named intWrapper, in memory (because we used the new keyword with that class
only once). So, any work done on intWrapper is done to the same object. Consequently, when we
increment intWrapper.objectInt, the change makes it back to the main method, because the main
method still looks at the same spot in memory. That is, intWrapper continues to be at the same location
in memory, and so we change that object where we could not change a primitive.
If all that seems confusing, you're in good company. It stumped me enough that I remember clearly,
thirty years later, when I first realized that something (a function in Fortran, in fact) was working on the
pass-by-reference model. It's a tricky concept, but you have to master it to be able to program in Java
(and many other languages).
Java has a particular reason for passing objects by reference, by the way. Suppose you have a
complex object. Such a class might have several fields, and many of those fields might themselves be
references to other objects (remember the composition technique), and so on, to any depth you can
imagine (object stacks, as such things are called, are often many layers deep). What exactly is the value of
Free download pdf