Concepts / Instance Variables and Instance Methods

Instance Variables and Instance Methods

A variable holding null does not refer to any object. Null is the actual value stored in the variable, so the variable is null, and it does not point to null.

  • Programming

Starting With a Prediction About null

Many programs store objects in variables, and one of the most common sources of runtime failure in Java involves a variable that holds null. Before learning the rules, it helps to test your intuition. The idea developed in this article is that a variable holding null is a variable whose value is null, and that this is not the same thing as a variable that points to something called null. The rest of the article rebuilds that idea from the variable's point of view and then shows what goes wrong when code treats a null variable as if it held an object.

What do you think happens?

Suppose a variable std of a class type holds null, and a program then tries to refer to the instance variable test1 through it. What do you expect to happen?

  • The program reads the value of test1 and continues normally

  • The program refers to test1 of an object that is created automatically

  • Java throws a NullPointerException while the program runs

Reveal answer
Answer:

Java throws a NullPointerException while the program runs.

Referring to instance variables or instance methods through a null variable is illegal. There is no object behind the variable, so there are no instance variables to refer to, and Java throws a NullPointerException at run time.

What a Variable Holds When It Is Null

Many learners picture a variable as an arrow that aims at something. When a variable has no object to aim at, they often imagine the arrow pointing at a special target called null. That picture feels natural, and it leads to a predictable set of errors later on.

The correct description is different. Null is an actual value. It is not a hidden pointer that leads somewhere else. A variable whose type is given by a class can hold a null reference, written in Java as the keyword null, and when it does, the variable itself holds that value. So we describe the variable as being null. The phrase 'points to null' is considered incorrect because it places null at the far end of an arrow, as if null were a place. Null is the content of the variable.

The difference between the two situations can be seen side by side. In one case, the variable holds a null reference, so there is no object behind it. In the other case, the variable holds a valid object reference, so it leads to an object that has its own instance variables. The diagram below lays these two cases next to each other.

std (case A)nullstd (case B)reference to an objectPlayerData objecthas its own instancevariablesrefers to
What does a reference variable actually store when it is null, and how does that differ from a variable that refers to an object?

When a Variable Can Hold null

A variable can hold null when its type is given by a class. You store null in it the same way you store any other value, by assigning null to it. Java also lets you test whether the variable currently holds null, by comparing the variable with the keyword null. The source uses the comparison std == null for this purpose.

java
Notes on the code
  • PlayerData is a class type, so std can hold a null reference
  • Assigning null stores the keyword null as the value of std
  • The comparison std == null tests whether std currently holds null

The test does not create an object or change the variable. It only reports what the variable currently holds. This matters because a program often needs to check first, and only use the variable when it holds a real object reference.

What Happens When a Null Variable Is Used

With a valid object reference, a program can refer to instance variables and instance methods through the variable. With a null reference, the same request has no target, because the object that would hold those instance variables does not exist. The source states the rule directly: if the value of a variable is null, it is illegal to refer to instance variables or instance methods through that variable, because there is no object and so no instance variables to refer to.

The trigger is specific. Suppose std is null. Writing std.test1 asks for an instance variable through a variable with no object behind it. Java treats this as an illegal request and throws a NullPointerException while the program runs. The flowchart below follows the decision Java makes when code reaches into an object through a variable.

Code reachesstd.test1uses the variable stdDoes std hold null?NullPointerExceptionthrown at run timeRead test1 from theobjectstd refers to a real objectcheckyesno
What sequence of steps occurs when code uses a variable that holds null, and at which step does Java throw the exception?
java
Output
NullPointerException
Notes on the code
  • The assignment std = null is accepted without any error
  • The failure appears on the line that uses std, not on the line where null was stored
  • The useful debugging question is which variable held null at the point of use
Debugging

When this error appears, trace the variable's value line by line. Find the last point where std was assigned, confirm whether that assignment stored null, and then check the line where std was used. The gap between the two lines is where the program diverged from what you expected.

Instance Variables Belong to Each Object

Definition

An object created from a class is an instance of that class, and the variables it contains are called instance variables. The word 'instance' names the object, so an instance variable is simply a variable that lives inside one particular object.

The key fact is where these variables live. Instance variables are part of the object, not part of the class. The class describes which variables an object will have, but the values belong to each individual object. This is why two objects created from the same class can hold different data at the same time.

The source illustrates this with a PlayerData class. When an object is created from it, that object is an instance of PlayerData, and the name and age variables are instance variables in that object. The example below is an original illustration of the same idea, with two objects built from one class.

java
Notes on the code
  • p1 and p2 are two separate instances of the PlayerData class
  • The name and age instance variables exist in each object
  • Setting p1.age does not change p2.age, because each object holds its own values
PlayerData classdescribes name and ageobject p1name: Ana, age: 20object p2name: Ben, age: 35instance ofinstance of
When two objects are created from the same class, how do their instance variables relate to the class and to each other, and where does each value live?

Instance Methods and Logical Containment

The same idea extends to behavior. The subroutines that an object contains are called instance methods. The source states that instance methods are the non-static methods, and that they become part of objects created from the class. Because an instance method is logically part of the object, you can think of the object as carrying its behavior along with its data. The object contains both its instance variables and its instance methods in this logical sense.

Many beginners picture object-oriented programming like a set of cookie cutters. The class is the cutter, and every object made from it is a full, independent copy of everything the class describes, including the behavior. Under that picture, if a class has an instance method and you create three objects from it, you would expect three separate copies of that method's code in memory, one inside each object.

The cookie cutter picture is a misconception. The mistake is taking the word 'contains' too literally. It is not literally true that each object contains its own copy of the compiled code for an instance method. The compiled code for a method is a single thing that the class defines. What each object has is a logical relationship to that method: the method is one of the things that belongs to the object, and the object is the thing you call the method on.

Static Methods Versus Instance Methods

Not every method belongs to objects. The source contrasts two kinds. Static methods are part of the class, and they are associated with the class, not with objects. Non-static methods, which are the instance methods, become part of objects created from the class. Keeping this contrast in mind prevents a common confusion about where a method lives.

FeatureStatic methodInstance method (non-static)
Belongs toThe classObjects created from the class
Is it associated with objects?No, it is associated with the classYes, it becomes part of each object
Logically part ofThe classEach object that the class creates
Stored codeA single definition owned by the classA single definition owned by the class, logically shared by its objects
Typical question it answersWhat does the class do as a whole?What does this particular object do with its own data?

Static and instance methods, as described in the source

Mistakes Learners Make With null and Instance Members

  • Common mistake

    Describing a null variable as pointing to null

    What it looks like

    Saying that std points to null, as if null were a destination

    Why it fails

    Null is the actual value stored in the variable, so the variable is null. There is no object at the far end of an arrow.

    Do this instead

    Say that std holds null, and that there is no object behind it

  • Common mistake

    Expecting the error on the line that stores null

    What it looks like

    Assuming std = null fails immediately, and then being confused when a later line fails

    Why it fails

    The assignment of null is accepted. The failure happens on the line that refers to an instance variable or instance method through std.

    Do this instead

    Look for the line that uses the variable, and trace back to find which assignment stored null

  • Common mistake

    Using a null variable to reach an instance variable

    What it looks like

    Writing std.test1 when std holds null

    Why it fails

    The rule is that referring to instance variables or instance methods through a null variable is illegal, and Java throws a NullPointerException.

    Do this instead

    Test with std == null first, and only use std when it refers to a real object

  • Common mistake

    Believing each object stores its own copy of method code

    What it looks like

    Imagining three objects of a class each holding a separate copy of an instance method

    Why it fails

    The source says it is not literally true that each object contains its own copy of the compiled code. The method is a single definition that the class provides.

    Do this instead

    Think of the method as logically belonging to each object, while its code is defined once

  • Common mistake

    Treating static methods as belonging to objects instead of the class

Checking Your Understanding With a Scenario

EASY

A program creates a PlayerData variable called std and assigns null to it. Later, the program refers to std.age. Trace the value of std line by line. At which line does the program fail, and what kind of exception does Java throw? Then describe, in your own words, what std holds at the moment of failure without using the phrase 'points to'.

Hints
  • Ask what std holds after the assignment, not what it refers to
  • Consider whether an object exists behind std at the moment age is requested
  • Recall which exception Java throws when an instance member is reached through a null variable
MEDIUM

Two PlayerData objects are created, p1 and p2. Change p1.name and confirm that p2.name is unaffected. Then explain why the instance variables can differ between the two objects, while the definition of the PlayerData class is shared by both.

Hints
  • Instance variables are part of the object, not the class
  • The class describes which variables an object will have, and the values belong to each object

Key Takeaways

  • A variable holding null does not refer to any object. Null is the actual value stored in the variable, so the variable is null, and 'points to null' is the wrong description.
  • Using a null variable to refer to an instance variable or instance method is illegal, and Java throws a NullPointerException while the program runs, at the line where the variable is used.
  • An object created from a class is an instance of that class. Its instance variables are part of the object, so each object holds its own values.
  • Instance methods, the non-static methods, logically become part of each object, but it is not literally true that each object stores its own copy of the compiled code.
  • Static methods are part of the class and are associated with the class, not with objects.