Concepts / Static Members and Shared Class Data

Static Members and Shared Class Data

A class definition is a blueprint that declares the instance variables and instance methods every object of that class will include

  • Programming

Why Start With a Blueprint

Before you can create objects, you need a description of what those objects will look like. In Java, that description is a class definition. Think of it as a blueprint. It does not hold any particular student, grade, or result on its own, but it states what every object built from it will contain and what it will be able to do.

Keep one question in mind as you read this article: when a class is used to create several students, which parts are shared by all of them, and which parts belong to each student separately? The answer decides how the code behaves. It is also the reason a method can return different results for different students even though the method was written only once.

Reading the Student Blueprint

The class below is a small Student definition. It is an illustrative class written to match the members named in the source: a name, three test scores, and a method that computes an average. Read it closely before you run anything. Notice what it does not do. It does not assign a name or grades to anyone, and it does not compute an average for anyone. It only declares what the members are and how the average is calculated.

Code walkthrough
public class Student {
    String name;
    int test1;
    int test2;
    int test3;

    double getAverage() {
        return (test1 + test2 + test3) / 3.0;
    }
}
  1. 1
    The class line declares a kind of object called Student. It does not create any student yet.
  2. 2
    The four lines inside the class declare what each Student will store. These are data declarations, not values.
  3. 3
    The getAverage method describes how an average is computed from the three test values. It has no separate copy for each student; it is written once in the class.
  • String name; is an instance variable that will hold a separate name for each student
  • int test1; int test2; int test3; are instance variables that hold each student's test values
  • double getAverage() is an instance method declared once inside the class
  • The method body reads the test values of whichever object it is called on

The class has two kinds of members to learn to read. Variables store data, and methods work with that data. Both are declared inside the class, and both belong to individual objects. The two subsections below take each kind in turn.

Watching Two Objects Take Shape

A class definition does not produce a student by itself. Objects are created from the blueprint, and each object is given its own set of values for the instance variables. The code below creates two students from the same Student class. It is an illustrative example written for this article, not code from the source.

java

After this code runs, there are two objects built from one blueprint. Object a has its own name, test1, test2, and test3. Object b also has its own set of the same four variables, and they hold different values. Changing b.test1 does not change a.test1, because each object holds its own copy of the instance variables. The diagram shows the layout of these two independent sets of data, with the class sitting above them as the source of their shape.

Student classdeclares fields andgetAverage()Object a (Ana)name = Ana, test1 = 90,test2 = 80, test3 = 70Object b (Ben)name = Ben, test1 = 60,test2 = 75, test3 = 90createscreates
When two objects are created from the same class, where does each object's instance variable data live, and how do the two copies stay separate?

Calling getAverage on Each Student

What do you think happens?

After the two students above are created, what do you think a.getAverage() and b.getAverage() each return?

  • Both return 80.0, because the method is written once

  • a returns 80.0 and b returns 75.0, because each call reads that object's own test values

  • Both return 75.0, because the last object created is used for both calls

Reveal answer
Answer:

a.getAverage() returns 80.0 and b.getAverage() returns 75.0.

The method is written once in the class, but each call reads the test values of the object it is called on. For a, the values are 90, 80, and 70, giving 240 divided by 3, which is 80.0. For b, the values are 60, 75, and 90, giving 225 divided by 3, which is 75.0.

java
Output
80.0
75.0

The two calls use the same method code and produce different results. The question is not whether getAverage() exists, since it is written only once in the class. The question is whose test values it uses at the moment of the call. The first call reads Ana's values; the second reads Ben's. The diagram compares the two calls side by side.

a.getAverage()reads 90, 80, 70Result for a80.0b.getAverage()reads 60, 75, 90Result for b75.0computescomputes
Why does calling the same instance method on two different objects of the same class return different results?
Worked example

Tracing getAverage for Ben

Given object b with test1 = 60, test2 = 75, and test3 = 90, what does b.getAverage() return?

  1. 1
    Identify the object

    The call is b.getAverage(), so the method reads the instance variables of object b, not of object a.

  2. 2
    Read the values

    Inside the method, test1, test2, and test3 refer to b's values: 60, 75, and 90.

  3. 3
    Compute the sum

    60 plus 75 plus 90 equals 225.

  4. 4
    Divide by three

    225 divided by 3.0 equals 75.0, which is the returned result.

Result

b.getAverage() returns 75.0.

Where Shared Class-Level Data Differs

Everything so far has been about instance members, which belong to individual objects. The plan's title names a second kind of member, the static member, which is shared class-level data. The contrast matters for reading code. An instance member's value is kept separately for each object, as the two Student objects showed. A shared class-level member is a single member associated with the class itself rather than with any one object.

The Student class in this article declares no static members. That is why it exists to create objects rather than to hold data shared by all students. If you see a member declared without the static keyword inside a class, read it as an instance member that each object will have its own value for.

QuestionInstance memberShared class-level (static) member
Who owns the value?Each individual objectThe class as a whole
Example in this articlename, test1, test2, test3, getAverage()None; the Student class declares no static members
Can two objects hold different values?YesNot as separate per-object copies
Why this article's class has itGives every student its own dataNot used here

Reading instance members against shared class-level members

Mistakes When Reading Class Members

  • Common mistake

    Thinking the class itself holds a student's grades

    What it looks like

    Reading the Student class and concluding that Ana's test1 is 90 because it appears in the code

    Why it fails

    The class only declares what the members are. It does not assign values to anyone; the values come when objects are created.

    Do this instead

    Treat the class as a description. Look for the object creation code to find the values.

  • Common mistake

    Assuming a method written once returns the same result everywhere

    What it looks like

    Expecting a.getAverage() and b.getAverage() to both return 80.0 because the method is defined once

    Why it fails

    The method reads the instance variables of the object it is called on, so different objects supply different data.

    Do this instead

    Ask which object the call is made on, then read that object's values.

  • Common mistake

    Expecting a change to one object to affect another

    What it looks like

    Setting b.test1 = 100 and then expecting a.test1 to change as well

    Why it fails

    Each object holds its own copy of the instance variables.

    Do this instead

    Change the value on the specific object you mean, and check that object's variables separately.

  • Common mistake

    Confusing the blueprint's declaration of a member with a value stored for a particular student

Practice Tracing a Third Student

EASY

Using the Student class from this article, suppose you add this code: Student c = new Student(); c.name = "Chen"; c.test1 = 100; c.test2 = 85; c.test3 = 70; Then trace what c.getAverage() returns. Also state whose test values the method reads, and confirm that a.getAverage() still returns 80.0.

Hints
  • Identify the object before the dot in c.getAverage(), and read only that object's test values.
  • Add 100, 85, and 70, then divide the sum by 3.0.
  • Calling c.getAverage() does not change a's values, so a.getAverage() is unaffected.
MEDIUM

Without running any code, explain in one or two sentences why a.getAverage() and c.getAverage() can return different results even though both calls use the same method.

Hints
  • Refer to whose instance variables the method reads.
  • Instance variables are stored per object, so each object supplies its own data.

Key Takeaways

  • A class definition is a blueprint that declares the instance variables and instance methods every object of that class will include, but it does not hold any particular object's values.
  • Instance variables such as name, test1, test2, and test3 hold separate values for each object created from the class.
  • An instance method such as getAverage() is written once in the class but computes its result from the data of whichever object it is called on.
  • The same method call can return different results for different objects, because the object before the dot supplies the data the method reads.
  • A shared class-level (static) member differs from instance members in where its value is kept: one class-level value rather than a separate value per object. The Student class here declares no static members.