Head First Java, 2nd Edition

Read HFJ online

9: Head First Java, 2nd Edition Life and Death of an Object

The big picture (p. 235)

This chapter is where we discuss not only constructors, but also how memory management works in Java.

Some important concepts that you are supposed to get from this chapter are:

Chapter 9, page-by-page

page 236-238: Stack vs. Heap, how the Stack Works, local vs. instance variables

These three pages should be studied together.

On page 236, we see the division between stack and heap in Java, in terms of where things are stored, which is similar, though subtly different from how things happen in C/C++ (as I’ll explain in the notes below.)

On page 237 we see the idea of “stack frames” (also known as “activation records” or “call frames”), which I’m hoping you’ve seen before in CS8, CS16, CS24 and/or CS32—but if not, here’s your chance to get caught up.

Page 238 focuses on the distinction between the reference variable and the object it points to—the case of a variable on the stack “referring to” (or “pointing to”) an object on the heap.

I will definitely put questions on the exam about the material on these two pages. Understanding what is on the stack and what is on the heap is crucial for understanding how to write efficient code, not only in Java, but in just about every modern programming language.

I am hopeful that you’ve encountered these ideas before in CS16, CS24 and possibly CS32—so that what is new here is just the Java portion of this material. So let’s compare this with what we know about C++:

One big difference between C++ and Java: it is possible, in C++ to create an object on the stack. For example, in the following C++ function, the Dog object d is on the stack. And, the destructor function for Dog will get invoked as soon as we return from function foo:

#include "dog.h"

void foo() 
{
     Dog d;
     cout << "Dog's name is " << d.getName() << endl
}

If we wanted a Dog on the heap in C++, we’d use a pointer:

#include "dog.h"

void bar() 
{
     Dog *p;
     p = new Dog;
     cout << "Dog's name is " << p->getName() << endl;
}

Note that:

In Java, by contrast, ALL objects are on the heap, because there is no concept of a variable for an object that isn’t a reference (i.e. a pointer.)

Note also that we can have:

Finally, note that:

Note that the picture on p. 237 shows the local variables and parameters “inside” the call frame, whereas in some other pictures, you may have seen them “on top of” the call frame. If you were actually writing a Java compiler or a JVM, those kind of details would matter—and later on, in courses such as CMPSC160 and CMPSC162, you’ll discuss those concepts, perhaps—but for our purposes of CMPSC56, it doesn’t really matter. The important thing is to know that they are:

Methods vs. Functions

Note that I will sometimes “slip up” and use the word “function” rather than method when describing those things in Java that you “call”.

In fact, Java has no functions other than methods, so it is “proper” to only use the word “method” in describing that things in Java that in any other language might be called functions. If I do use the word “function” when referring to Java, I really mean “method”.

I use the words interchangeably for two reasons:

Some potential exam questions

  1. Write a Java class that will compile and run (i.e. it needs a main() method) that has (at least) the following four variables: a, b, c, and d, each instance of which will have the properties indicated.
    • a should be a primitive variable that will be stored on the stack
    • b should be an object reference that will be stored on the stack
      • note: the references is on the stack, even though the object it refers to will always be on the Heap in Java.)
    • c should be a primitive variable that will always be stored on the heap.
    • d should be an object reference that will always be stored on the heap
      • note: here I want the reference variable itself to be on the heap, not just the object it refers to.)

    It does not matter if the class is useful in practice—the purpose of this question is to test your understanding of how Java works.

  2. Write a Java class with a main method that illustrates that it is possible for there to be two or more occurrences of a given instance variable (say title in class Book) on the heap at the same time.

    You should have a line of code System.out.println("now"); that will be printed at a moment when there are two instances of the instance variable title in memory.

    It does not matter if the class is useful in practice—the purpose of this question is to test your understanding of how Java works.

  3. Write a Java class with a main method that illustrates that it is possible for there to be two or more instances of a given local variable or parameter (say n) on the stack at the same time.

    You should have a line of code System.out.println("now"); that will be printed at the precise moment when there are two instances of the local variable or parameter n in memory.

    It does not matter if the class is useful in practice—the purpose of this question is to test your understanding of how Java works.

page 239-245: Constructors in Java

page 246: a specific note about no-arg constructors

page 247-249: more on constructors

page 250-257: inheritance and constructors

page 258-263: lifetime and scope

page 264-265: fireside chat

page 266-271: exercises