Concepts / Declaring Static Member Variables

Declaring Static Member Variables

A static member variable is shared by all instances of its class, so it holds one value for the class as a whole.

  • Programming

A Number That Describes the Whole Class

Suppose a program has a class that holds a number describing the whole class rather than any one object made from it. A count of how many players are in a poker game is a good example. Each player might be represented by an object, but the number of players belongs to the game as a whole. Where should that number live, and how does code in another class reach it?

A static member variable answers both questions. It is declared inside a class, and it holds one value for the class as a whole. This article follows that value through three moments: when it is created and shared, when it is read from inside its own class, and when it is read from a different class. Along the way you will see what happens when one object changes it.

Where a Shared Value Lives

Definition

A static member variable is shared by all instances of its class, so it holds one value for the class as a whole. Instances are the individual objects created from the class. Because the variable belongs to the class rather than to any one object, there is a single variable that every object of that class refers to.

Contrast this with a non-static member variable. Each object created from a class gets its own separate copy of a non-static variable, so changing it in one object does not change it in another. A static member variable is different: there is one copy for the whole class, no matter how many objects are created. The diagram below shows this difference for three objects of the same class.

count (static)3object 1 count2object 2 count7object 3 count4one shared valueone shared valueone shared value
If three objects of the class are created, how many copies of the static variable exist, and where does each object's value live compared with a non-static variable?

Read the diagram carefully. The static variable count appears once, at the top, with a single value. The three per-object counts are separate boxes, each with its own value, and they are not the static variable. The per-object entries are shown only to make the contrast visible: a non-static variable would have one box for every object, while a static variable has only one box for the entire class.

Reading the Value Inside Its Own Class

Here is the poker situation written as Java code. The class Poker declares a static member variable named numberOfPlayers. Code inside Poker can name the variable directly, with no class name in front of it. The declaration uses the static keyword and is public, which the source describes as the clearest case of a static member variable that can be used from outside its class.

Code walkthrough
public class Poker {
    public static int numberOfPlayers = 0;

    public static void addPlayer() {
        numberOfPlayers = numberOfPlayers + 1;
    }

    public static void showPlayers() {
        System.out.println(numberOfPlayers);
    }
}
  1. 1
    Line 2 declares the static member variable numberOfPlayers and gives it the starting value 0.
  2. 2
    Lines 4 to 6 define addPlayer. The line inside it reads numberOfPlayers, adds 1, and stores the result back in the same variable.
  3. 3
    Lines 8 to 10 define showPlayers, which prints the current value using the plain name numberOfPlayers.
  4. 4
    Neither method needs the words Poker dot in front of the variable, because both are written inside the class that defines it.
  • numberOfPlayers is declared static, so one value is stored for the whole Poker class
  • addPlayer refers to numberOfPlayers by its plain name
  • showPlayers also uses the plain name, because it is inside the defining class

Reaching the Value from Another Class

Code in a different class cannot rely on the plain name alone. It must write a compound identifier. The form is the class name, then a dot, then the variable name, written as class-name.variable-name. The dot joins the two parts into one identifier that tells the reader exactly which class owns the variable.

Mathclass name, the owner.dot joins the two partsPIstatic member variable namequalifiesselects
In an expression like Math.PI, which part names the class, which part names the member, and what does the dot connect?

The source gives two familiar examples from everyday Java. The System class contains the public static member variable out, which is used in other classes as System.out. The Math class contains the public static member variable PI, which is used as Math.PI. In both cases the class name comes first, then the dot, then the variable name. Every time you write System.out.println, you are using this same pattern.

java
Output
4
Notes on the code
  • Poker.numberOfPlayers is the compound identifier used from a different class
  • The plain name numberOfPlayers would not work here, because Table is not the defining class

Following One Change Across Objects

Because a static member variable has only one value for the class, a change made through one object is visible through every other object. Follow the value of numberOfPlayers as two objects of Poker take turns. Before you read the answer, decide what the second object will see.

What do you think happens?

The first object sets numberOfPlayers to 4. What value does the second object read from numberOfPlayers?

  • 0

  • 4

  • It depends on which object was created first

Reveal answer
Answer:

4

A static member variable is shared by all instances of its class. There is only one stored value, so the second object reads the same 4 that the first object wrote.

3before the change4after the first object setsit4read by the second objectfirst object writes 4second object reads the same value
After one object changes the static variable, what value do the other objects see, and how does that differ from changing a non-static variable?

The diagram shows one stored value moving from 3 to 4. The second object does not hold its own copy that needs updating, because it reads the one shared variable. A non-static variable would behave differently: each object would hold its own value, and writing to one object's copy would leave the others unchanged.

Mistakes With Shared Values

The following mistakes are common when students first work with static member variables. Each one comes from treating the variable as if it belonged to a single object.

  • Common mistake

    Writing only the plain name from another class

    What it looks like

    Table code that writes numberOfPlayers = 4 when numberOfPlayers is defined in Poker

    Why it fails

    The plain name is only meaningful inside the defining class. Outside it, the name does not identify which class owns the variable.

    Do this instead

    Write the compound identifier Poker.numberOfPlayers in the other class.

  • Common mistake

    Reversing the parts of the compound identifier

    What it looks like

    Writing numberOfPlayers.Poker instead of Poker.numberOfPlayers

    Why it fails

    The class name must come first, then the dot, then the variable name. The source gives the form as class-name.variable-name.

    Do this instead

    Put the class name before the dot and the variable name after it.

  • Common mistake

    Expecting each object to keep its own count

    What it looks like

    Assuming that a second object created from Poker starts with a fresh numberOfPlayers of 0

    Why it fails

    A static member variable is shared by all instances of its class, so there is one value for the whole class.

    Do this instead

    Treat the value as belonging to the class, and use a non-static variable when each object needs its own value.

  • Common mistake

    Forgetting that a change made through one object is visible to every other object

Tracking Games in GuessingGame

The source applies the same idea to a GuessingGame class from earlier in its chapter. Two static member variables are added. The first, gamesPlayed, keeps track of how many games the user has played. The second, gamesWon, keeps track of how many of those games the user has won. Both are static because each describes the game as a whole, not a single round.

Worked example

Counting games across rounds

A GuessingGame class has static member variables gamesPlayed and gamesWon, both starting at 0. A user plays three rounds and wins two of them. What are the final values, and where do they live?

  1. 1
    Identify the scope

    Both variables describe the whole game, so both are static and each has one value for the class.

  2. 2
    Count the rounds

    Each finished round increases gamesPlayed by 1, so after three rounds gamesPlayed is 3.

  3. 3
    Count the wins

    Each won round increases gamesWon by 1, so after two wins gamesWon is 2.

  4. 4
    Check the storage

    Because both are static, the values are stored once for the class, not once for each round object that may be created.

Result

gamesPlayed is 3 and gamesWon is 2, stored as single values for the GuessingGame class.

Practice Reading Compound Identifiers

EASY

A class named Counter declares a public static member variable named count. Write the statement that a different class, Report, would use to print the value of count. Then say which part of your identifier names the class, which part names the member, and what the dot connects.

Hints
  • Inside Report, the plain name count would not identify Counter's variable.
  • The form is class-name.variable-name, with the class name first.
  • The answer has the shape Counter.count inside a print statement.
MEDIUM

Two objects are created from Poker. The first object adds one player with addPlayer, and then the second object adds one more. Using the shared-value idea, what does numberOfPlayers hold after both calls, and why does the second object's call not start from 0?

Hints
  • There is only one numberOfPlayers for the whole class.
  • Think about what the first call stored, and where the second call reads from.

Key Takeaways

  • A static member variable is shared by all instances of its class, so it holds one value for the class as a whole rather than one value per object.
  • Inside the class that defines a static member variable, the plain variable name is enough to reach it.
  • From a different class, the variable must be written as the compound identifier class-name.variable-name, as in System.out and Math.PI.
  • A change made through one object to a static member variable is seen by every other object of that class, because all of them refer to the same single value.